android-fragments - tablayout - viewpager con fragments
Fragmento ya ha agregado IllegalStateException en viewpager (1)
FragmentStatePagerAdapter
diseño FragmentStatePagerAdapter
sugiere crear un nuevo Fragment
para cada página ( ver el ejemplo de Google ). Y desafortunadamente no puedes leer un Fragment
una vez que fue agregado a un FragmentManager
(lo que ocurre implícitamente dentro del adaptador), de ahí la excepción que enfrentas. Entonces, la forma oficial de Google es crear nuevos fragmentos y dejarlos ser destruidos y recreados por el adaptador.
Pero si desea reutilizar páginas y utilizar un patrón analógico de ViewHolder, debe apegarse a las vistas en lugar de a los fragmentos. Las vistas podrían eliminarse de sus padres y reutilizarse, a diferencia de los fragmentos. Extienda PagerAdapter
e implemente instantiateItem()
esta manera:
@Override
public Object instantiateItem(ViewGroup container, final int position) {
//determine the view type by position
View view = viewPager.findViewWithTag("your_view_type");
if (view == null) {
Context context = container.getContext();
view = LayoutInflater.from(context).inflate(R.layout.page, null);
view.setTag("your_view_type");
} else {
ViewGroup parent = (ViewGroup) item.getParent();
if (parent != null) {
parent.removeView(item);
}
}
processYourView(position, view);
container.addView(view, MATCH);
return view;
}
Debe agregar un poco de lógica adicional para determinar el tipo de vista por posición (ya que tiene 3 tipos de vistas), creo que puede resolverlo.
Estoy usando viewpager para visualizar imágenes. Solo necesito tres fragmentos básicamente: imagen previa para vista previa, imagen de visualización actual y próxima imagen para vista previa. Me gustaría simplemente mostrar una vista previa de la imagen anterior y siguiente, que cambiará a la imagen completa cuando el usuario realmente deslice hacia ella. Así que estoy pensando en usar 3 fragmentos para lograr esto. El código está abajo:
private class ImagePagerAdapter extends FragmentStatePagerAdapter implements ViewPager.OnPageChangeListener {
private ImageFragment mImageFragment;
private ImagePreviewFragment mPreviousPreviewFragment;
private ImagePreviewFragment mNextPreviewFragment;
public ImagePagerAdapter(FragmentManager fm, ImageFragment image, ImagePreviewFragment previous, ImagePreviewFragment next) {
super(fm);
mImageFragment = image;
mPreviousPreviewFragment = previous;
mNextPreviewFragment = next;
}
@Override
public Fragment getItem(int position) {
if (position == mPager.getCurrentItem()) {
mImageFragment.display(position);
return mImageFragment;
}
if (position < mPager.getCurrentItem()) {
mPreviousPreviewFragment.display(position - 1);
return mPreviousPreviewFragment;
}
mNextPreviewFragment.display(position + 1);
return mNextPreviewFragment;
}
@Override
public int getCount() {
return 100;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.d(TAG, "onPageScrolled");
}
@Override
public void onPageSelected(final int position) {
Log.d(TAG, "onPageSelected " + position);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
}, 500);
}
@Override
public void onPageScrollStateChanged(int state) {
Log.d(TAG, "onPageScrollStateChanged " + state);
}
@Override
public int getItemPosition(Object item) {
return POSITION_NONE;
//return POSITION_UNCHANGED;
}
}
Básicamente, precreé tres fragmentos para mostrar la vista previa anterior / siguiente y la imagen actual, y los devolví para getItem (). También notificodatasetchange () en onpageselected () para hacer las tres posiciones para actualizar el fragmento cuando el usuario desliza a la página nueva.
Pero el problema es que arrojará
Fragment already added IllegalStateException
cuando los fragmentos se agregan por segunda vez. Creo que es porque se ha agregado antes. Puedo crear un nuevo fragmento cada vez, pero creo que es un desperdicio. Entonces, ¿cómo puedo reutilizar el fragmento ya creado y simplemente actualizarlos?
Gracias, Simon