Objetos de comunicación entre fragmentos múltiples en ViewPager
Tengo 5 fragmentos en ViewPager
usados para llenar el objeto del negocio con varios campos paso a paso, en cada paso algunos de esos campos serán fijados. He leído muchos artículos sobre la comunicación entre los fragmentos pero no me siento cómodo de la forma en que otros prefieren, así que después de pensar en CÓMO debo hacer esto en mi caso, finalmente empiezo a pensar en el uso de objeto singleton modelo que todos los fragmentos pueden acceder fácilmente a sus campos y llenarlos en pasos específicos.
Como soy nuevo en android, quiero escuchar a expertos sobre el uso de singleton en lugar de pasar datos entre fragmentos como la interfaz implementada (Parece que es tan complicado y difícil de mantener). Cualquier consejo será útil.
- ¿Por qué un servicio Android no es singleton cuando se prueba?
- Acceso al objeto GoogleApiClient en Todas las actividades
- Fragmento no UI vs Singleton
- Java.lang.IllegalStateException: La aplicación PagerAdapter cambió el contenido del adaptador sin llamar a PagerAdapter # notifyDataSetChanged android
- Métodos estáticos o singleton, ¿cuál elegir?
- Singleton con contexto en Android
- Acceder a los campos singleton mediante un método estático
- Cambiar Actividades sin el uso de una Intención
- Cómo declarar variables globales en Android?
- ¿Puedo obtener cierta eficiencia al declarar a los miembros apropiados "estáticos" en la actividad de Android?
- Servicio de Android Creación de una nueva instancia de clase Singleton
- AlarmManager estático en Android
- ¿Es una práctica aceptable usar Objetos Singleton para guardar el estado o compartir datos entre Actividades?
Mientras que el enfoque singleton parece fácil de implementar y entender que es la manera no a la mejor manera de lograr lo que necesita. Una de las razones es que el objeto modelo o como lo llaman objeto de negocio vive fuera del contexto de su actividad, lo que puede crear errores difíciles de encontrar. Por ejemplo, en caso de que más de una instancia de su clase de actividad sea creada por el sistema y ambas mantienen referencia a su singleton. ¿Ves cómo pierdes la pista de tus objetos?
Lo que haría es
- Hacer que mi modelo de objeto para implementar
Parcelable
que va a odiar al principio, pero una vez que seParcelable
a que se convertirá en el mejor amigo de su modelo - Puesto que su modelo es
parcelable
ahora usted puede pasarlo fácilmente entre los fragmentos, las actividades, e incluso excepto él en preferencias compartidas. Una cosa importante a tener en cuenta aquí cuando pasa suparcelable
entre fragmento o actividad es como pasar por valor, es decir, cada vez que se crea una nueva instancia. -
Establecer el argumento de su fragmento o si ya está instanciado a continuación, obtener argumentos y añadir su modelo. aquí hay un ejemplo: si un fragmento no está activo todavía:
Bundle args = new Bundle(); args.putParcable("businessObject", yourBusinessObjectThatIsParcable); yourFragment.setArguments(args);
De lo contrario:
yourFragment.getArguments().putParcelable("businessObject", yourBusinessObjectThatIsParcable);
-
En su fragmento quizás en el método onCreateView obtenga su objeto de modelo como este
MyParcableObject mpo = (MyParcableObject)getArguments().getParcelable("businessObject")
y utilice el conjunto de datos que desee. -
Cuando termine de editar su objeto en el botón haga clic o en el método onPause actualizó los argumentos de su fragmento de la misma manera
getArguments().putParcelable("businessObject", mpo);
-
en su última página o último fragmento puede pasar su objeto a su actividad, aquí es cómo hacerlo
A pesar de que se ve engorroso, pero es una práctica que usted necesita para acostumbrarse a como desarrollador de Android. Usted obtiene mucho más control cuando su modelo implementa parcelable
.
Otra forma de hacer lo que necesita es a través de patrón de delegación, pero se utiliza principalmente para devoluciones de llamada aunque se pueden pasar objetos también.
No recomendaría un singleton global. Hay dos razones principales:
- Por definición, un singleton limita su aplicación a una sola instancia del objeto principal de negocio. Si usted (o un diseñador, o el jefe de su jefe jefe) decide tener múltiples de estos ViewPagers a la vez, tendrá que cambiar su arquitectura de todos modos.
- La forma de pensar de Android es esperar que tu usuario pueda poner tu aplicación en segundo plano y usar otras aplicaciones antes de volver a tu aplicación. Si el sistema decide matar tu aplicación en segundo plano, tu objeto de memoria singleton se destruirá y tu usuario habrá perdido todo su progreso. La manera correcta de guardar un estado de Android es mantener el estado en una Actividad o Fragmento, guardarlo adecuadamente en
onSaveInstanceState()
y restaurarlo enonCreate()
.
Todos los Fragmentos del ViewPager pueden obtener una referencia a la actividad principal a través de una llamada a getActivity()
. O si su ViewPager está dentro de un Fragmento, entonces todos los fragmentos pueden acceder al fragmento padre a través de una llamada a getParentFragment()
. A continuación, puede emitir el resultado a la clase apropiada (o mejor aún, interfaz) y realizar llamadas de método para pasar datos de un lado a otro. Lleve un registro de sus datos comerciales en la actividad / fragmento principal. De esta manera, no es necesario un singleton global
Por ejemplo,
public class MyParentFragment extends Fragment { private String mPageOneData; private int mPageTwoData; private List<Date> mPageThreeData; public void setPageOneData(String data) { mPageOneData = data; } ... } public class PageOneFragment extends Fragment { private void sendDataToParent(String data) { Fragment f = getParentFragment(); if (f != null && f instanceof MyParentFragment) { MyParentFragment parent = (MyParentFragment) f; f.setPageOneData(data); } } }
-
puede guardar sus datos en el evento onSaveInstanceState () de la actividad en caso de que su proceso entre en segundo plano. puede restaurar sus datos en el evento onCreate () utilizando Bundle y getExtras ().
-
puede guardar sus datos en la clase de aplicación y los datos seguirán estando allí en caso de que su proceso entre en segundo plano.
prefiero la primera opción porque no quieres hacer un desastre en la clase de aplicación con todos los datos de diferentes actividades y fragmentos. Espero poder ayudar
¿Has probado EventBus ?
No estoy seguro de si es el mejor enfoque, especialmente cuando su pregunta es demasiado amplia, sin embargo, será genial con sólo 5 fragmentos.
Espero eso ayude
Supongo que en su MainActivity hay un ViewPager
, y FragmentOne
será uno de los fragmentos dentro del paginador de vista. Aquí MainActivity se está comunicando con el FragmentOne para actualizar su adaptador. La esperanza es clara.
En su MainActivity, agregue esta interfaz:
public interface Updateable { public void update(); }
Implementar esta interfaz en un fragmento que necesita actualizarse y escribir el código para notificar al adaptador dentro del método de update
:
public class FragmentOne extends Fragment implements MainActivity.Updateable { ... @Override public void update() { // YOUR CODE TO UPDATE HERE, FOR EXAMPLE, HERE I'M UPDATING THE ADAPTER if ( adapter != null ) { adapter.notifyDataSetChanged(); } else { Log.d("LOG_TAG", "null"); } } ... }
Llame al método de update
de MainActivity cuando el fragmento se cargue primero. Puede hacer esto sobreescribiendo el método getItemPosition
en su PagerAdapter
, como esto:
@Override public int getItemPosition(Object object) { if ( object != null && object instanceof FragmentOne ) { FragmentOne f = (FragmentOne) object; f.update(); } return super.getItemPosition(object); }
Finalmente, debe llamar a notifyDataSetChanged () de su adaptador viewPager. Esto obligará al adaptador de su viewpager a llamar al método getItemPosition.
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { int previousState; @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { if (previousState == ViewPager.SCROLL_STATE_SETTLING && state == ViewPager.SCROLL_STATE_IDLE) { if ( viewPagerAdapter.getItem(viewpager.getCurrentItem()) instanceof Pictures ) { Log.d("LOG_TAG", "New Position=" + viewpager.getCurrentItem()); viewPagerAdapter.notifyDataSetChanged(); } } previousState = state; } });
Antes de elegir cualquier opción, tenga en cuenta el usuario puede navegar o abrir cualquier otra aplicación (s) por lo que perdió sus datos.
Usted puede utilizar onSaveInstanceState
pero de alguna manera difícil de mantener (como usted dijo que son nuevos en android). Usted puede ir con con singleton usando
- Base de datos – Utilice cuando quiera almacenar mantener varios registros, pero tiene que crear un getter / setter de base de datos o utilizar cualquier ORM como RushOrm, etc.
-
SharefPreference
(preferiblemente) – Si desea utilizar valores individuales.
En ambos casos crearás un objeto singleton y accederás a sus propiedades en tus fragmentos.
hacer sus objetos parcelable y después pasarlo a otros fragmentos usando el paquete. es decir, bundle.putParcelable (obj) parcelable es muy eficiente y rápido.
debería motivarte
- Las líneas de fondo definen el tamaño de la vista
- Error de secuencia de comandos de compilación, método DSL de Gradle sin soporte encontrado: 'release ()'!