with viewpager tablayout showing pageradapter not multiple fragments con android-fragments android-viewpager illegalstateexception fragmentstatepageradapter

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