sectionspageradapter - viewpager android studio
Añadir/Eliminar páginas a ViewPager dinámicamente (9)
Me gustaría agregar o eliminar páginas de mi visor de página dinámicamente. ¿Es eso posible?
Aquí hay una solución alternativa a esta pregunta. Mi adaptador
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);
}
}
Código para eliminar y agregar dinámicamente
//remove the pages. basically call to method removeAllViews from ViewPager
pagerAdapter.removePages();
pagerAdapter.addPage(pass your fragment);
Después del consejo de Peri Hartman , comenzó a funcionar después de configurar null
en el adaptador de ViewPager y volver a colocar el adaptador una vez que se eliminaron las vistas. Antes de esto la página 0 no mostraba los contenidos de su lista.
Basándome en otras respuestas y otros recursos, he terminado con este código.
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();
}
}
MainActivity :
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);
}
}
Para eliminar páginas:
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 tiene el mismo código.
Los diseños son simples diseños de ViewPager / Fragment con android.support.v4.view.ViewPager
con container
identificación y Fragment TextView
con id section_label
.
Recursos:
Esta solución funciona bien por el momento:
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());
}
}
Tenga en cuenta:
- Su clase de
Item
debe contener una implementación correspondiente para los métodosequals
yhashCode
- Su clase
ItemView
debe contener getter y setter para su objetoItem
.
Estoy seguro de que ha creado un adaptador extendiendo PageAdapter, por lo que hay un método:
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
}
Para obtener un ejemplo detallado de lo mismo, simplemente lea este ejemplo .
Primero: anule el método pagerAdapter "getItemPosition"
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
Segundo: elimine el enlace de datos con el adaptador y llame al adaptador.
Sí, dado que ViewPager obtiene las Vistas secundarias de un PagerAdapter, puede agregar nuevas páginas / eliminar páginas en eso, y llamar a .notifyDataSetChanged () para volver a cargarlo.
Sí, el código debería ser así:
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;
}
}
Pero hay un error. Si el elemento actual es 0, y para eliminar la página 0, no se actualizará la pantalla al instante, no he encontrado una solución para esto.
Sí. Puede agregar o eliminar vistas dinámicamente al PagerAdapter que las proporciona al ViewPager y llamar a notifyDataSetChanged()
desde el PagerAdapter para alertar al ViewPager afectado sobre los cambios. Sin embargo, cuando lo haga, debe anular la getItemPosition(Object)
de PagerAdapter, que les dice si los elementos que están mostrando actualmente han cambiado de posición. De forma predeterminada, esta función está configurada en POSITION_UNCHANGED
, por lo que ViewPager no se actualizará inmediatamente si no anula este método. Por ejemplo,
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;
}
}
}
Aunque, si simplemente desea agregar o eliminar la vista temporalmente de la pantalla, pero no del conjunto de datos de PagerAdapter, intente usar setPrimaryItem(ViewGroup, int, Object)
para ir a una vista particular en los datos de destroyItem(ViewGroup, int, Object)
y destroyItem(ViewGroup, int, Object)
para eliminar una vista de la pantalla.
@Bind(R.id.pager)
ViewPager pager;
int pos = pager.getCurrentItem();
pager.removeViewAt(pos);