Je voudrais ajouter ou supprimer des pages de mon pageur de vue dynamiquement. Est-ce possible?
Oui, puisque ViewPager obtient les vues enfant d'un PagerAdapter, vous pouvez ajouter de nouvelles pages/supprimer des pages dessus et appeler .notifyDataSetChanged () pour le recharger.
Oui. Vous pouvez ajouter ou supprimer des vues de manière dynamique au PagerAdapter qui les fournit au ViewPager et appeler notifyDataSetChanged()
à partir du PagerAdapter pour alerter le ViewPager concerné des modifications. Toutefois, lorsque vous procédez ainsi, vous devez remplacer la getItemPosition(Object)
du PagerAdapter, qui indique si les éléments qu’ils affichent actuellement ont changé de position. Par défaut, cette fonction est définie sur POSITION_UNCHANGED
. Par conséquent, ViewPager ne s'actualisera pas immédiatement si vous ne substituez pas cette méthode. Par exemple,
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(object) {
return mList.indexOf(object);
} else {
return POSITION_NONE;
}
}
}
Toutefois, si vous souhaitez simplement ajouter ou supprimer temporairement la vue, mais pas du jeu de données de PagerAdapter, essayez d'utiliser setPrimaryItem(ViewGroup, int, Object)
pour accéder à une vue particulière dans les données de PagerAdapter et destroyItem(ViewGroup, int, Object)
pour supprimer une vue de l'affichage.
Oui, le code devrait être comme ça:
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;
}
}
Mais il y a un bug. Si l'élément actuel est 0 et que vous souhaitez supprimer la page 0, l'écran ne sera pas actualisé instantanément. Je n'ai pas trouvé de solution à ce problème.
Je suis sûr que vous avez créé un adaptateur en étendant PageAdapter. Il existe donc une méthode:
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
}
Pour un exemple détaillé identique, il suffit de lire cet exemple .
Voici une solution alternative à cette question. Mon adaptateur:
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 à supprimer et à ajouter dynamiquement
//remove the pages. basically call to method removeAllViews from ViewPager
pagerAdapter.removePages();
pagerAdapter.addPage(pass your fragment);
Après l’avis de Peri Hartman , cela a commencé à fonctionner après que j’ai défini null
sur l’adaptateur ViewPager et que je le remette à nouveau après la suppression des vues. Avant cela, la page 0 ne montrait pas le contenu de sa liste.
Tout d'abord: remplacer la méthode pagerAdapter "getItemPosition"
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
Deuxièmement: supprimez la liaison de données avec adapter.et appelez adapter.notifydatachanged
@Bind(R.id.pager)
ViewPager pager;
int pos = pager.getCurrentItem();
pager.removeViewAt(pos);
Sur la base d’autres réponses et d’autres ressources, j’ai terminé avec ce code.
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();
}
}
Activité principale:
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);
}
}
Pour supprimer des pages:
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 a le même code.
Les dispositions sont simples: ViewPager/Fragment, avec Android.support.v4.view.ViewPager
avec id container
et Fragment TextView
avec id section_label
.
Ressources:
Cette solution fonctionne bien pour l'instant:
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());
}
}
Notez s'il vous plaît:
Item
doit contenir une implémentation correspondante pour les méthodes equals
et hashCode
ItemView
doit contenir getter et setter pour votre objet Item
.