studio - viewpager slider in android
Objetos de comunicación entre múltiples fragmentos en ViewPager (7)
puede guardar sus datos en el evento onSaveInstanceState () de la actividad en caso de que su proceso pase a segundo plano. puede restaurar sus datos en el evento onCreate () usando Bundle y getExtras ().
puede guardar sus datos en la clase de aplicación y los datos seguirán allí en caso de que su proceso pase a segundo plano.
Prefiero la primera opción porque no desea hacer un lío en la clase de la aplicación con todos los datos de diferentes actividades y fragmentos. Espero poder ayudar :)
Tengo 5 fragmentos en ViewPager
utilizan para rellenar el objeto comercial con varios campos, paso a paso, en cada paso se establecerán algunos de esos campos. He leído muchos artículos sobre la comunicación entre fragmentos, pero no me siento cómodo como prefirieron los demás, así que después de pensar en CÓMO debo hacer esto en mi caso, finalmente empiezo a pensar en usar el objeto modelo Singleton al que todos los fragmentos pueden acceder fácilmente. A sus campos y rellénelos en pasos específicos.
Como soy nuevo en Android, quiero saber de los expertos sobre el uso de singleton en lugar de pasar datos entre fragmentos, como la interfaz implementada (parece ser tan complicado y difícil de mantener). Cualquier consejo será de ayuda.
¿Has EventBus ?
No estoy seguro de si es el mejor enfoque, especialmente cuando su pregunta es demasiado amplia, sin embargo, será genial con solo 5 fragmentos.
Espero eso ayude
Antes de elegir cualquier opción, tenga en cuenta que el usuario puede navegar o abrir cualquier otra aplicación para que pierda sus datos.
Puedes usar onSaveInstanceState
pero será algo difícil de mantener (como dijiste que eres nuevo en Android). Puedes ir con singleton usando
- Base de datos: utilícela cuando desee almacenar mantener varios registros, pero debe crear un recopilador / configurador de bases de datos o usar cualquier ORM como RushOrm, etc.
-
SharefPreference
(preferiblemente) - Si desea utilizar valores únicos.
En ambos casos, creará un objeto singleton y accederá a sus propiedades en sus fragmentos.
Si bien el enfoque de singleton parece fácil de implementar y entender, no es la mejor manera de lograr lo que necesita. Una de las razones es que su objeto modelo o como lo llama un objeto comercial vive fuera del contexto de su actividad, lo que puede crear errores difíciles de encontrar. Por ejemplo, en caso de que el sistema cree más de una instancia de su clase de actividad y ambas mantengan la referencia a su singleton. ¿Ves cómo pierdes la pista de tus objetos?
Lo que yo haría es
- Haz que mi objeto modelo se implemente en
Parcelable
loParcelable
al principio, pero una vez que teParcelable
a él, se convertirá en el mejor amigo de tu modelo. - Ya que su modelo es
parcelable
ahora, puede pasarlo fácilmente entre fragmentos, actividades e incluso guardarlo en preferencias compartidas. Una cosa importante que se debe tener en cuenta aquí cuando pasa suparcelable
entre el fragmento o la actividad es como pasar por valor, es decir, cada vez que se crea una nueva instancia. Establezca el argumento de su fragmento o si ya está instanciado, obtenga argumentos y agregue su modelo. Aquí hay un ejemplo: si un fragmento aún no está activo:
Bundle args = new Bundle(); args.putParcable("businessObject", yourBusinessObjectThatIsParcable); yourFragment.setArguments(args);
De lo contrario:
yourFragment.getArguments().putParcelable("businessObject", yourBusinessObjectThatIsParcable);
En su fragmento, tal vez en el método onCreateView, obtenga su objeto modelo como este
MyParcableObject mpo = (MyParcableObject)getArguments().getParcelable("businessObject")
y utilícelo para establecer los datos que desee.Cuando termine de editar su objeto con el clic del botón o con el método onPause, actualice los argumentos de su fragmento de la misma manera que
getArguments().putParcelable("businessObject", mpo);
en su última página o último fragmento puede pasar su objeto a su actividad, here está cómo hacerlo
Aunque parezca engorroso, es una práctica a la que debes acostumbrarte 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 del Patrón de delegación, pero se utiliza principalmente para las devoluciones de llamada, aunque también puede pasar objetos.
Supongo que en su MainActivity hay un ViewPager
, y FragmentOne
será uno de los fragmentos dentro del paginador de la vista. Aquí MainActivity se está comunicando a FragmentOne para actualizar su adaptador. La esperanza es clara.
En tu MainActivity agrega esta interfaz:
public interface Updateable {
public void update();
}
Implemente esta interfaz en un fragmento que deba actualizarse y escriba 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
desde MainActivity cuando el fragmento se carga primero. Puede hacer esto anulando 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;
}
});
Yo 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 de negocio principal. Si usted (o un diseñador o el jefe de su jefe) alguna vez decide tener varios de estos ViewPagers a la vez, tendrá que cambiar su arquitectura de todos modos.
- La "forma de pensar de Android" es esperar que su usuario ponga su aplicación en segundo plano y utilice otras aplicaciones antes de volver a la aplicación. Si el sistema decide matar su aplicación en segundo plano, su objeto de memoria singleton se destruirá y su usuario habrá perdido todo su progreso. La forma correcta de Android de guardar el estado es mantener el estado en una Actividad o Fragmento, guardarlo adecuadamente en
onSaveInstanceState()
y restaurarlo enonCreate()
.
Todos los Fragmentos en el 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 principal a través de una llamada a getParentFragment()
. Luego, puede enviar el resultado a la clase apropiada (o mejor aún, la interfaz) y hacer llamadas de método para pasar datos de un lado a otro. Mantenga un registro de los datos de su negocio en la actividad / fragmento principal. De esta manera, no necesitas 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);
}
}
}
haga sus objetos parcelables y luego páselos a otros fragmentos usando el paquete. es decir, bundle.putParcelable (obj) parcelable es muy eficiente y rápido.
debería motivarte