Vraag Pagina's dynamisch toevoegen / verwijderen aan ViewPager


Ik wil pagina's dynamisch toevoegen of verwijderen uit mijn view-pager. Is dat mogelijk?


52
2017-11-09 05:50


oorsprong


antwoorden:


Ja, aangezien ViewPager de onderliggende weergaven van een PagerAdapter krijgt, kunt u nieuwe pagina's toevoegen / pagina's verwijderen en .notifyDataSetChanged () aanroepen om deze opnieuw te laden.


17
2017-11-09 05:59



Ja. U kunt op dynamische wijze weergaven toevoegen of verwijderen aan de PagerAdapter die deze aan de ViewPager levert en belt notifyDataSetChanged() vanuit de PagerAdapter om de getroffen ViewPager op de hoogte te stellen van de wijzigingen. Wanneer u dit echter doet, moet u het getItemPosition(Object) van de PagerAdapter, die hun vertelt of de items die ze momenteel tonen van positie zijn veranderd. Standaard is deze functie ingesteld op POSITION_UNCHANGED, zodat de ViewPager niet onmiddellijk wordt vernieuwd als u deze methode niet overschrijft. Bijvoorbeeld,

public class mAdapter extends PagerAdapter {
    List<View> mlist;

    public void addView(View view, int index) {
        mList.add(index, view);
        notifyDataSetChanged();
    }

    public void removeView(int index) {
        mList.remove(index);
        notifyDataSetChanged();
    }

    @Override
    public int getItemPosition(Object object) {
        if (mList.contains((View) object) {
            return mList.indexOf((View) object);
        } else {
            return POSITION_NONE;
        }
    }
}

Hoewel, als u de weergave tijdelijk wilt toevoegen of verwijderen uit het display, maar niet uit de dataset van de PagerAdapter, probeer dan setPrimaryItem(ViewGroup, int, Object) voor het bezoeken van een bepaalde weergave in de gegevens van de PagerAdapter en destroyItem(ViewGroup, int, Object) voor het verwijderen van een weergave uit het display.


22
2018-05-28 14:11



Ja, de code zou zo moeten zijn:

public int addPage(View view, int position) {
        if ((position >= 0) && (position < getSize())) {
            myPagerAdapter.mListViews.add(position, view);
            myPagerAdapter.notifyDataSetChanged();
            return position;
        } else {
            return -1;
        }
    }

public View removePage(int position) {
        if ((position < 0) || (position >= getSize()) || (getSize()<=1)) {
            return null;
        } else {
            if (position == mPager.getCurrentItem()) {
                if(position == (getSize()-1)) {
                    mPager.setCurrentItem(position-1);
                } else if (position == 0){
                    mPager.setCurrentItem(1);
                }
            }
            View tempView = myPagerAdapter.mListViews.remove(position);
            myPagerAdapter.notifyDataSetChanged();
            return tempView;
        }
    }

Maar er is een fout. Als het huidige item 0 is en om pagina 0 te verwijderen, wordt het scherm niet meteen vernieuwd. Ik heb hier geen oplossing voor gevonden.


16
2018-04-08 22:30



Ik weet zeker dat je een adapter hebt gemaakt door PageAdapter uit te breiden, dus er is één methode:

 @Override
 public void destroyItem(View collection, int position, Object view) {
           ((ViewPager) collection).removeView((View) view);
 }

Voor een gedetailleerd voorbeeld hiervan, ga gewoon door dit voorbeeld.


3
2017-11-09 05:54



Hier is een alternatieve oplossing voor deze vraag. Mijn adapter:

private class PagerAdapter extends FragmentPagerAdapter implements 
              ViewPager.OnPageChangeListener, TabListener {

    private List<Fragment> mFragments = new ArrayList<Fragment>();
    private ViewPager mPager;
    private ActionBar mActionBar;

    private Fragment mPrimaryItem;

    public PagerAdapter(FragmentManager fm, ViewPager vp, ActionBar ab) {
        super(fm);
        mPager = vp;
        mPager.setAdapter(this);
        mPager.setOnPageChangeListener(this);
        mActionBar = ab;
    }

    public void addTab(PartListFragment frag) {
        mFragments.add(frag);
        mActionBar.addTab(mActionBar.newTab().setTabListener(this).
                            setText(frag.getPartCategory()));
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    @Override
    public int getCount() {
        return mFragments.size();
    }

    /** (non-Javadoc)
     * @see android.support.v4.app.FragmentStatePagerAdapter#setPrimaryItem(android.view.ViewGroup, int, java.lang.Object)
     */
    @Override
    public void setPrimaryItem(ViewGroup container, int position,
            Object object) {
        super.setPrimaryItem(container, position, object);
        mPrimaryItem = (Fragment) object;
    }

    /** (non-Javadoc)
     * @see android.support.v4.view.PagerAdapter#getItemPosition(java.lang.Object)
     */
    @Override
    public int getItemPosition(Object object) {
        if (object == mPrimaryItem) {
            return POSITION_UNCHANGED;
        }
        return POSITION_NONE;
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        mPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) { }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) { }

    @Override
    public void onPageScrollStateChanged(int arg0) { }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) { }

    @Override
    public void onPageSelected(int position) {
        mActionBar.setSelectedNavigationItem(position);
    }

    /**
     * This method removes the pages from ViewPager
     */
    public void removePages() {
        mActionBar.removeAllTabs();

                    //call to ViewPage to remove the pages
        vp.removeAllViews();
        mFragments.clear();

        //make this to update the pager
        vp.setAdapter(null);
        vp.setAdapter(pagerAdapter);
    }
}

Code om dynamisch te verwijderen en toe te voegen

//remove the pages. basically call to method removeAllViews from ViewPager
pagerAdapter.removePages();

pagerAdapter.addPage(pass your fragment);

Na het advies van Peri Hartman, het begon te werken nadat ik het had ingesteld null naar de ViewPager-adapter en plaats de adapter opnieuw nadat de weergaven zijn verwijderd. Voordien liet de pagina 0 niet de lijstinhoud zien.


3
2018-05-05 20:52



Ten eerste: overschrijf de methode pagerAdapter "getItemPosition"

@Override
public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

Ten tweede: verwijder de gegevensbinden met de adapter.en beladapter.nietvermeldingsgegeven


2
2018-05-12 01:50



@Bind(R.id.pager)
ViewPager pager;
int pos = pager.getCurrentItem();
pager.removeViewAt(pos);

2
2017-12-08 06:18



Deze oplossing werkt tot nu toe goed:

 public class CustomPagerAdapter extends PagerAdapter {

    private final List<Item> objects = new ArrayList<>();

    public CustomPagerAdapter(List<Item> objects) {
        if (objects != null) {
            this.objects.add(objects);
        }
    }

    @Override
    public int getCount() {
        return objects.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        Item item = (Item) object;
        ItemView itemView = (ItemView) view;
        return Objects.equals(itemView.getItem(), item);
    }

    @Override
    public int getItemPosition(Object object) {
        Item item = (Item) object;
        int idx = objects.indexOf(item);
        return idx == -1 ? POSITION_NONE : idx;
    }

    @Override
    public Item instantiateItem(ViewGroup container, int position) {
        Item item = objects.get(position);

        final int id = generateViewIdForItem(item);
        ItemView itemView = new ItemView(container.getContext());
        itemView.setId(id);
        container.addView(itemView);

        itemView.setItem(item);

        return item;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        Item item = (Item) object;
        final int id = generateViewIdForItem(item);
        View view = container.findViewById(id);
        if (view != null) {
            container.removeView(view);
        }
    }

    public void update(@Nullable List<Item> objects) {
        this.objects.clear();
        if (objects != null) {
            this.objects.addAll(objects);
        }
        notifyDataSetChanged();
    }

    public void clear() {
        update(null);
    }

    /* add remove/update/add methods if you need, don't forget to call notifyDataSetChanged */

    private static int generateViewIdForItem(Item item) {
        return Math.abs(item.hashCode());
    }
}

Houd er rekening mee dat:

  • Jouw Item klasse moet een overeenkomstige implementatie bevatten voor equals en hashCode methoden
  • Jouw ItemView klasse moet getter en setter bevatten voor jouw Item voorwerp.

0
2017-10-25 12:38



Gebaseerd op andere antwoorden en andere bronnen die ik met deze code heb beëindigd.

CustomPagerAdapter:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CustomPagerAdapter extends PagerAdapter {

  private List<Fragment> pages = new ArrayList<>();
  private Map<Fragment, Integer> fragmentsPosition = new HashMap<>();

  private Fragment currentPrimaryItem;
  private FragmentManager fragmentManager;
  private FragmentTransaction currentTransaction;


  public CustomPagerAdapter(FragmentManager fragmentManager) {
    this.fragmentManager = fragmentManager;
  }

  @Override
  public Object instantiateItem(ViewGroup container, int position) {
    if (currentTransaction == null) {
      currentTransaction = fragmentManager.beginTransaction();
    }

    Fragment pageFragment = pages.get(position);
    String tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG);
    Fragment fragment = fragmentManager.findFragmentByTag(tag);

    if (fragment != null) {
      if (fragment.getId() == container.getId()) {
        currentTransaction.attach(fragment);
      }
      else {
        fragmentManager.beginTransaction().remove(fragment).commit();
        fragmentManager.executePendingTransactions();
        currentTransaction.add(container.getId(), fragment, tag);
      }
    }
    else {
      fragment = pageFragment;
      currentTransaction.add(container.getId(), fragment, tag);
    }

    if (fragment != currentPrimaryItem) {
      fragment.setMenuVisibility(false);
      fragment.setUserVisibleHint(false);
    }

    return fragment;
  }

  @Override
  public int getCount() {
    return pages.size();
  }

  @Override
  public void destroyItem(ViewGroup container, int position, Object object) {
    if (currentTransaction == null) {
      currentTransaction = fragmentManager.beginTransaction();
    }

    currentTransaction.detach((Fragment) object);
  }

  @Override
  public void setPrimaryItem(ViewGroup container, int position, Object object) {
    Fragment fragment = (Fragment) object;

    if (fragment != currentPrimaryItem) {
      if (currentPrimaryItem != null) {
        currentPrimaryItem.setMenuVisibility(false);
        currentPrimaryItem.setUserVisibleHint(false);
      }

      if (fragment != null) {
        fragment.setMenuVisibility(true);
        fragment.setUserVisibleHint(true);
      }

      currentPrimaryItem = fragment;
    }
  }

  @Override
  public void finishUpdate(ViewGroup container) {
    if (currentTransaction != null) {
      currentTransaction.commitAllowingStateLoss();
      currentTransaction = null;
      fragmentManager.executePendingTransactions();
    }
  }

  @Override
  public boolean isViewFromObject(View view, Object object) {
    return ((Fragment) object).getView() == view;
  }

  @Override
  public int getItemPosition(Object o) {
    Integer result = fragmentsPosition.get(o);

    if (result == null) {
      return PagerAdapter.POSITION_UNCHANGED;
    }

    return result;
  }

  // ---------------------------------- Page actions ----------------------------------

  public void addPage(Fragment fragment) {
    fragmentsPosition.clear();
    pages.add(fragment);
    notifyDataSetChanged();
  }

  public void removePage(int position) {
    fragmentsPosition.clear();

    Fragment pageFragment = pages.get(position);
    String tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG);

    Fragment fragment = fragmentManager.findFragmentByTag(tag);

    if (fragment != null) {
      fragmentsPosition.put(fragment, PagerAdapter.POSITION_NONE);
    }

    for (int i = position + 1; i < pages.size(); i++) {
      pageFragment = pages.get(i);
      tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG);
      fragment = fragmentManager.findFragmentByTag(tag);

      if (fragment != null) {
        fragmentsPosition.put(fragment, i - 1);
      }
    }

    pages.remove(position);
    notifyDataSetChanged();
  }

}

Hoofdactiviteit:

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

  public static final String FRAGMENT_TAG_ARG = "tag";

  private CustomPagerAdapter mCustomPagerAdapter;

  private ViewPager mViewPager;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mCustomPagerAdapter = new CustomPagerAdapter(getSupportFragmentManager());
    mCustomPagerAdapter.addPage(MainFragment.newInstance("Main_Title"));
    mCustomPagerAdapter.addPage(SecondaryFragment.newInstance("Secondary_Title"));

    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mCustomPagerAdapter);
  }

}

Om pagina's te verwijderen:

mCustomPagerAdapter.removePage(1);

MainFragment:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MainFragment extends Fragment {

  public static final String FRAGMENT_TAG = "MainFragment";

  public static MainFragment newInstance(String text) {
    return newInstance(text, FRAGMENT_TAG);
  }

  public static MainFragment newInstance(String text, String tag) {
    MainFragment fragment = new MainFragment();
    Bundle args = new Bundle();
    args.putString("text", text);
    args.putString(MainActivity.FRAGMENT_TAG_ARG, tag + "_" + fragment.hashCode());
    fragment.setArguments(args);
    return fragment;
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    TextView textView = (TextView) rootView.findViewById(R.id.section_label);
    textView.setText(getArguments().getString("text"));
    return rootView;
  }

}

SecondaryFragment heeft dezelfde code.

De lay-outs zijn eenvoudige ViewPager / Fragment-lay-outs met android.support.v4.view.ViewPager met id container en Fragment TextView met id section_label.

Middelen:


0
2018-01-12 22:07