with viewpager studio sectionspageradapter practice fragments example best and android android-fragments android-viewpager fragmentstatepageradapter

android - viewpager - fragmentpageradapter example



Guardar/Actualizar datos EditText de Fragment en un FragmentStatePagerAdapter (1)

Introducción

Tengo una actividad con un libro que contiene una lista de tipos de "página" y para manejar todas las páginas decidí usar un FragmentStatePagerAdapter en el que uno de mis fragmentos contiene una página.

Creé una interfaz para la comunicación entre cada fragmento en el busca 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 implementé la actividad padre, la interfaz para recibir los datos de un fragmento y almacenarlos en una página para guardarlos en la lista de arrays.

Cada fragmento tiene un EditText en el que el usuario puede escribir y yo configuro addTextChangedListener para captar el momento en que el usuario deja de escribir. Cuando el usuario se detiene a escribir en EditText, en onTextChanged (), invoco la función implementada en la actividad padre.

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 de 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, eliminé algunas partes como onClickListener, onPageSelectionListener y otros tipos de páginas que estoy creando en este momento.

El problema

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


Como puede ver en la imagen, si escribo algo en EditText2, aparecerá el mismo contenido en 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é capturar el cambio enfoque en lugar de utilizar AddTextChangedListener, pero no cambió nada.

2) Intenté implementar una lógica diferente utilizando onChangePageListener() , pero en este caso mBookViewPager.getCurrentItem() por lo que la actualización falla.

3) Probé todas estas publicaciones: una , dos , tres y cuatro .

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

Gracias


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

  1. para gestionar la implementación de la página actual 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 automáticamente carga privious y la siguiente vista para privent establece el buscapersonas 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 contraparte siempre a través de la instrucción else incluso para cualquier valor predeterminado.

    if (page instanceof BookPageText) { BookPageText bookPageText = (BookPageText) page; pageContent.putParcelable("page", bookPageText); }