Fragmento de actualización de ViewPager
Tengo una Activity
con un ViewPager
. También tengo un Dialog
que recuperará una lista con algunos artículos que el usuario elegirá. Ahora, ¿cómo puedo actualizar el Fragment
donde se supone que los Elementos se muestran como nuevas vistas adjuntas a este Fragmento?
Aquí está el adaptador de ViewPager
:
- Diferencia entre FragmentPagerAdapter y FragmentStatePagerAdapter
- Android ViewPager Detectar desplazamiento vertical
- ViewPager PagerAdapter no actualizar la vista
- ViewPager con mutiple niños visibles y seleccionado más grande.
- ¿Cómo puedo desactivar la precarga en un viewpager?
public static class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return 1; } @Override public android.support.v4.app.Fragment getItem(int position) { switch (position) { case 0: return new Fragment1(); default: return null; } } }
Ahora, aquí está el Fragment
:
public class Fragment1 extends Fragment{ @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); } @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } @Override public ViewGroup onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub ViewGroup view = (ViewGroup)inflater.inflate(R.layout.screen1, container, false); } return view; } }
Este es el método que quiero usar para agregar elementos a mi Fragment
private void addItem() { // Instantiate a new "row" view. final ViewGroup[] newViews = new ViewGroup[selectedItems.length]; for(int i = 0; i < selectedItems.length; i++){ newViews[i] = (ViewGroup) LayoutInflater.from(this).inflate( R.layout.animated_layout_item, mContainerView, false); // Set the text in each new row. ((TextView) newViews[i].findViewById(android.R.id.text1)).setText(selectedItems[i]); // Because mContainerView has android:animateLayoutChanges set to true, // adding this view is automatically animated. mContainerView.addView(newViews[i], 0); // Set a click listener for the "X" button in the row that will remove the row. OnClickListener listener = new MyAddItemListener(newViews[i], mContainerView, this); newViews[i].findViewById(R.id.delete_button).setOnClickListener(listener); } }
- Biblioteca de soporte de diseño de Android FAB en un fragmento ViewPager con diseño de coordinador
- ActionBarSherlock + Tabbed Fragments + ViewPager insider un fragmento
- Android: reutilizar fragmentos de ViewPager y FragmentPagerAdapter
- CoordinatorLayout dentro de otro CoordinatorLayout
- Android FragmentPagerAdapter con LoaderManager
- ViewPager - onCreateView no siempre se llama
- ViewPager parece reenable clipChildren al desplazarse si se configura PageTransformer
- Viewpager + webview, cómo detener la carga de la webview
Fragmento de actualización de ViewPager
Es necesario implementar el getItemPosition(Object obj)
.
Este método se llama cuando se llama
notifyDataSetChanged()
En su ViewPagerAdaper
. Implícitamente este método devuelve valor POSITION_UNCHANGED
que significa algo como esto: "Fragmento es donde debe estar así que no cambie nada".
Así que si necesita actualizar Fragment puede hacerlo con:
- Siempre devuelva
POSITION_NONE
del métodogetItemPosition()
. Lo que significa: "El fragmento debe ser siempre recreado" - Puede crear algún método update () que actualizará su Fragmento (el fragmento manejará las actualizaciones por sí mismo)
Ejemplo de segunda aproximación:
public interface Updateable { public void update(); } public class MyFragment extends Fragment implements Updateable { ... public void update() { // do your stuff } }
Y en FragmentPagerAdapter harás algo como esto:
@Override public int getItemPosition(Object object) { MyFragment f = (MyFragment ) object; if (f != null) { f.update(); } return super.getItemPosition(object); }
Y si usted elige el primer acercamiento puede parecer:
@Override public int getItemPosition(Object object) { return POSITION_NONE; }
Nota: Vale la pena pensar en un enfoque que recogerás.
Me enfrenté problema algunas veces para que en este caso siempre evitar FragmentPagerAdapter y utilizar FragmentStatePagerAdapter.
Funciona para mí. Espero que funcione para usted también.
Implemento una demo de aplicación siguiendo la respuesta de Sajmon. Sólo para cualquier otra persona que busque esta pregunta.
Puede acceder al código fuente de GitHub
En su anulación de PagerAdapter getItemPosition
@Override public int getItemPosition(Object object) { // POSITION_NONE makes it possible to reload the PagerAdapter return POSITION_NONE; }
Después de eso, agregue viewPager.getAdapter (). NotifyDataSetChanged (); Este código como a continuación
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { viewPager.getAdapter().notifyDataSetChanged(); } @Override public void onPageScrollStateChanged(int state) { } });
Deberia trabajar.
Respuesta aceptada no es entender, por eso agregó una solución fácil. Después de una larga lucha encontrar Solución de trabajo.
Apenas notifique a su adaptador , él está trabajando asombroso,
Código de referencia
void setAdapter(int position) { PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(pagerAdapter); // when notify then set manually current position. viewPager.setCurrentItem(position); pagerAdapter.notifyDataSetChanged(); }
Llame a este código cuando configure el adaptador y cuando desee actualizar la interfaz de usuario.
En Tu fragmento agrega este código para actualizar
((YourActivityName) getContext()).setAdapter(selectedTabPosition);
Utilice instanceof
para el contexto de conversión.
Este código comparte sólo ayudando al propósito que encuentran la solución.
Puede actualizar el fragmento de dos maneras diferentes,
Primera manera
Como @Sajmon
Es necesario implementar el getItemPosition(Object obj)
.
Este método se llama cuando se llama
notifyDataSetChanged()
Puedes encontrar un ejemplo en Github y más información en este post .
Segundo camino
Mi enfoque para actualizar fragmentos dentro del viewpager es usar el método setTag()
para cualquier vista instanciada en el método instantiateItem()
. Por lo tanto, cuando desea cambiar los datos o invalidar la vista que necesita, puede llamar al método findViewWithTag()
en ViewPager para recuperar la vista previamente instanciada y modificarla / usarla como desee sin tener que eliminar / crear una nueva vista Cada vez que desee actualizar algún valor.
@Override public Object instantiateItem(ViewGroup container, int position) { Object object = super.instantiateItem(container, position); if (object instanceof Fragment) { Fragment fragment = (Fragment) object; String tag = fragment.getTag(); mFragmentTags.put(position, tag); } return object; } public Fragment getFragment(int position) { Fragment fragment = null; String tag = mFragmentTags.get(position); if (tag != null) { fragment = mFragmentManager.findFragmentByTag(tag); } return fragment; }
Puedes encontrar un ejemplo en Github o más información en este post :
Tal vez su método para agregar elementos al fragmento debe ser público (colocado en Fragmento deseado) y debe tener el mismo parámetro que selectedItems.
Que lo hará visible de la actividad, que tendrá selectedItems array y voila ..
Ps mejor nombre it addItemsFromArray(typeOfSelectedItems[] pSelectedItems)
nombre de causa addItem()
es bastante undescriptive
Editar: stackoverflow acaba de sugerir un tema similar 🙂 Compruebe aquí para la implementación de la idea detallada .. 🙂
Muy simple para anular el método en el fragmento:
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser){ actionView(); } else{ //no } }
Una solución muy simple pero efectiva para actualizar tus vistas de fragmentos . Utilice el método setUserVisibleHint()
. Será llamado cuando el fragmento esté a punto de ser visible para el usuario. Allí puedes actualizar nuestra vista ( setText()
o setVisibility()
etc.)
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser){ //Write your code to be executed when it is visible to user } }
Funcionó en mi caso. ¡Espero eso ayude!
1) Cree un controlador en el fragmento que desea actualizar.
public static Handler sUpdateHandler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... sUpdateHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); // call you update method here. } }; }
2) En el cuadro de diálogo Actividad / Fragmento /, donde desee que se dispare la llamada de actualización, obtenga la referencia a ese controlador y envíe un mensaje (indicando que su fragmento debe actualizarse)
// Check if the fragment is visible by checking if the handler is null or not. Handler handler = TaskTabCompletedFragment.sUpdateHandler; if (handler != null) { handler.obtainMessage().sendToTarget(); }