Guardar / Actualizar los datos de EditText del fragmento en un FragmentStatePagerAdapter

Introducción

Tengo una actividad con un libro que contiene un arraylist de tipo "página" y para manejar todas las páginas que he decidido utilizar un FragmentStatePagerAdapter en el que uno de mi fragmento contiene una página.

Creé una interfaz para la comunicación entre cada fragmento en el buscapersonas y la actividad del padre. El método que necesito en esta interfaz es para actualizar una página mostrada en un fragmento, así que hice implementar a la actividad padre, la interfaz para recibir los datos de un fragmento y almacenarlos en una página para guardar en el arraylist.

Cada fragmento tiene un EditText en el que el usuario puede escribir y establecer un addTextChangedListener para capturar el momento en que el usuario deja de escribir. Cuando el usuario deja de escribir en el EditText, en el onTextChanged (), llamo a la función implementada en el padre de la actividad.

Este es mi código de actividad

public class BookEditorActivity implements BookEditorFragment.EditorFrToEditorActInterface { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.book_editor_activity); Bundle extras = getIntent().getExtras(); b = (Book) extras.get("book"); setBookViewPager(b); } private void setBookViewPager(Book b) { mBookViewPager = (ViewPager) findViewById(R.id.book_editor_pager); mBookViewPagerAdapter = new BookViewPagerAdapter(getSupportFragmentManager(), b); mBookViewPager.setAdapter(mBookViewPagerAdapter); } @Override public void saveBookPageTextContent(String textContent) { int current = mBookViewPager.getCurrentItem(); if (b.getPages().get(current) instanceof BookPageText) { ((BookPageText) b.getPages().get(current)).setContentPageText(textContent); } } @Override public void newBookPageText() { int current = mBookViewPager.getCurrentItem(); BookPageText bookPageText = new BookPageText(); bookPageText.setContentPageText(""); b.getPages().add(b.getPages().size() - 1, bookPageText); setIndicator(current + 1, b.getPages().size()); mBookViewPagerAdapter.notifyDataSetChanged(); } } 

Este es el código del fragmento

 public class BookEditorFragment extends Fragment { private EditorFrToEditorActInterface mCallback; public interface EditorFrToEditorActInterface { void newBookPageText(); void saveBookPageTextContent(String s); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle pageContent = getArguments(); if (pageContent != null) { page = pageContent.getParcelable("page"); } } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (page instanceof BookPageText) { BookPageText bookPage = (BookPageText) page; mView = inflater.inflate(R.layout.book_page_text_fragment, container, false); contentPage = (EditText) mView.findViewById(R.id.content_text); String contentPageText = bookPage.getContentPageText(); contentPage.setText(contentPageText.isEmpty() ? "" : Html.fromHtml(contentPageText)); contentPage.addTextChangedListener(new TextWatcher() { public void onTextChanged(CharSequence c, int start, int before, int count) { mCallback.saveBookPageTextContent(c.toString()); } public void beforeTextChanged(CharSequence c, int start, int count, int after) { } public void afterTextChanged(Editable c) { } }); } return mView; } @Override public void onAttach(Context context) { super.onAttach(context); try { mCallback = (EditorFrToEditorActInterface) context; } catch (ClassCastException e) { throw new ClassCastException(context.toString() + " must implement NewPageInterface"); } } @Override public void onDetach() { mCallback = null; super.onDetach(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.editor_new_text: mCallback.newBookPageText(); break; } } } 

Este es el código FragmentStatePagerAdapter

 public class BookViewPagerAdapter extends FragmentStatePagerAdapter { private ArrayList<Object> bookPages = new ArrayList<>(); private final SparseArray<WeakReference<BookEditorFragment>> instantiatedFragments = new SparseArray<>(); public BookViewPagerAdapter(FragmentManager fm, Book b) { super(fm); this.bookPages = b.getPages(); } @Override public Fragment getItem(int position) { Object page = bookPages.get(position); Bundle pageContent = new Bundle(); if (page instanceof BookPageText) { BookPageText bookPageText = (BookPageText) page; pageContent.putParcelable("page", bookPageText); } BookEditorFragment fragment = new BookEditorFragment(); fragment.setArguments(pageContent); return fragment; } @Override public int getCount() { return bookPages.size(); } @Override public Object instantiateItem(final ViewGroup container, final int position) { final BookEditorFragment fragment = (BookEditorFragment) super.instantiateItem(container, position); instantiatedFragments.put(position, new WeakReference<>(fragment)); return fragment; } @Override public void destroyItem(final ViewGroup container, final int position, final Object object) { instantiatedFragments.remove(position); super.destroyItem(container, position, object); } @Nullable public Fragment getFragment(final int position) { final WeakReference<BookEditorFragment> wr = instantiatedFragments.get(position); if (wr != null) { return wr.get(); } else { return null; } } @Override public int getItemPosition(Object object) { int position = bookPages.indexOf(object); return position == -1 ? POSITION_NONE : position; } } 

Debido a la longitud del código he eliminado algunas partes como el onClickListener, onPageSelectionListener y otros tipos de páginas que estoy creando ahora mismo.

El problema

Esta lógica parece funcionar correctamente, pero cada vez que modifico el contenido de un EditText en un fragmento, el fragmento de cierre a la izquierda también se actualiza y no sé por qué.

Introduzca aquí la descripción de la imagen
Como se puede ver en la imagen, si escribo algo en el EditText2, el mismo contenido aparecerá en el EditText1 y esto no tiene sentido.

Otro problema es cuando agrego una nueva página en el libro, la página se crea correctamente, pero con el contenido de la página anterior y esto no tiene sentido. (¡de nuevo!)

Mis intentos

1) Intenté coger el onFocusChange en vez de usar el addTextChangedListener, pero nada cambió.

2) He intentado implementar una lógica diferente usando el onChangePageListener() , pero en este caso mBookViewPager.getCurrentItem() el mBookViewPager.getCurrentItem() para que la actualización salga mal.

3) He intentado esto todo esto puestos: uno , dos , tres y cuatro .

¿Cómo puedo corregir este comportamiento extraño? ¿Es posible que el problema está en la forma en que las páginas de referencia en la ArrayList del libro?

Gracias

Algunos de los posibles errores que encontré en su implementación son.

  1. Gestionar la página actual posetion implementar

      mViewPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int p) { current = p; Log.e("Postion", "" + p); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) {} @Override public void onPageScrollStateChanged(int arg0) {} }); 
  2. Viewpager carga automáticamente la vista privious y siguiente a privent que establece pager OffscreenPageLimit llamando a mathod

     mViewPager.setOffscreenPageLimit(); 
  3. Siempre asegúrese de que si está utilizando la instrucción if en el adaptador, debe poner su contra parte siempre a través de la sentencia else , incluso para cualquier valor por defecto.

     if (page instanceof BookPageText) { BookPageText bookPageText = (BookPageText) page; pageContent.putParcelable("page", bookPageText); } 
  • Android - fragmento de niño no carga la segunda vez dentro de FragmentStatePagerAdapter
  • Salta dinámicamente páginas en ViewPager
  • Cómo agregar la página dinámicamente en FragmentStatePagerAdapter
  • Fragmentos que no se vuelven a crear por FragmentStatePagerAdapter después de volver a la instancia de Fragmento principal
  • GetResources de FragmentStatePagerAdapter
  • Cargar sólo un fragmento en ViewPager
  • Desplazamiento Dirección en ViewPager
  • Android: intenta invocar el método virtual 'void android.support.v4.app.Fragment.setMenuVisibility (boolean)' en una referencia de objeto nulo
  • Android FragmentStatePagerAdapter devuelve pantalla en blanco al recargar fragmentos de medio
  • FragmentStatePagerAdapter fuga de memoria (fragmentos anidados con viewpager)
  • Segundo conjunto de pestañas en un fragmento de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.