OnResume () no se llama al fragmento ViewPager cuando se utiliza Custom Loader

Version corta:

Tengo un fragmento que mantiene un ViewPager para mostrar otros dos fragmentos, llamémoslos FragmentOne y FragmentTwo . Cuando se inicia la aplicación FragmentOne es visible y FragmentTwo está fuera de la pantalla, haciéndose visible sólo cuando uno desliza la vista hacia la izquierda.

Normalmente onStart() y onResume() se invocan inmediatamente para ambos fragmentos tan pronto como se inicie la aplicación.

El problema que tengo es cuando FragmentOne inicia un Loader personalizado, entonces onResume() no se llama a FragmentTwo hasta que se hace completamente visible.

Captura de pantalla que muestra el problema

Preguntas:

¿Es este un problema con mi código o un error en la Biblioteca de soporte de Android? (El problema no ocurrió con la revisión 12 de la biblioteca, que comenzó con la revisión 13.)

Si se trata de un error en las revisiones 13 y 18, ¿existe alguna solución?

¿Hay algo mal con mi Loader personalizado?

Versión larga:

He construido una aplicación de ejemplo que demuestra el problema. He intentado reducir el código al mínimo pero todavía es mucho así que por favor tenga paciencia conmigo.

Tengo una MainActivity que carga un MainFragment que crea un ViewPager . Es importante para mi aplicación que el ViewPager sea mantenido por un Fragmento en lugar de una Actividad.

MainFragment crea un FragmentPagerAdapter que a su vez crea los fragmentos FragmentOne y FragmentTwo .

Empecemos con el fragmento interesante, los dos fragmentos:

FragmentOne es un ListFragment que utiliza un Loader personalizado para cargar el contenido:

 public class FragmentOne extends ListFragment implements LoaderCallbacks<List<String>> { private ArrayAdapter<String> adapter; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1); setListAdapter(adapter); setEmptyText("Empty"); } @Override public void onResume() { super.onResume(); // initializing the loader seems to cause the problem! getLoaderManager().initLoader(0, null, this); } @Override public Loader<List<String>> onCreateLoader(int id, Bundle args) { return new MyLoader(getActivity()); } @Override public void onLoadFinished(Loader<List<String>> loader, List<String> data) { adapter.clear(); adapter.addAll(data); } @Override public void onLoaderReset(Loader<List<String>> loader) { adapter.clear(); } public static class MyLoader extends AsyncTaskLoader<List<String>> { public MyLoader(Context context) { super(context); } @Override protected void onStartLoading() { forceLoad(); } @Override public List<String> loadInBackground() { return Arrays.asList("- - - - - - - - - - - - - - - - - - - foo", "- - - - - - - - - - - - - - - - - - - bar", "- - - - - - - - - - - - - - - - - - - baz"); } } } 

Es ese Loader que parece causar el problema. Comentar la línea initLoader hace que el ciclo de vida del fragmento funcione de nuevo como se esperaba.

FragmentTwo cambia su contenido basado en si onResume() ha sido invocado o no:

 public class FragmentTwo extends Fragment { private TextView text; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { text = new TextView(container.getContext()); text.setText("onCreateView() called"); return text; } @Override public void onResume() { super.onResume(); Log.i("Fragment2", "onResume() called"); text.setText("onResume() called"); } } 

Y aquí está el resto aburrido del código.

MainActivity :

 public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Fragment fragment = new MainFragment(); getSupportFragmentManager().beginTransaction().add(R.id.container, fragment).commit(); } } 

Layout activity_main :

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" /> 

MainFragment :

 public class MainFragment extends Fragment { private ViewPager viewPager; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View layout = inflater.inflate(R.layout.frag_master, container, false); viewPager = (ViewPager) layout.findViewById(R.id.view_pager); return layout; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); viewPager.setAdapter(new MyPagerAdapter(getChildFragmentManager())); } private static final class MyPagerAdapter extends FragmentPagerAdapter { public MyPagerAdapter(FragmentManager fragmentManager) { super(fragmentManager); } @Override public int getCount() { return 2; } @Override public Fragment getItem(int position) { if (position == 0) return new FragmentOne(); else return new FragmentTwo(); } } } 

Diseño: frag_master :

 <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> 

Parece ser un error en la biblioteca de soporte. El cambio a continuación resuelve el problema.

 // FragmentOne.java @Override public void onResume() { super.onResume(); Handler handler = getActivity().getWindow().getDecorView().getHandler(); handler.post(new Runnable() { @Override public void run() { // initialize the loader here! getLoaderManager().initLoader(0, null, FragmentOne.this); } }); } 

Otra solución que funcionó para mí fue usar el gestor de cargador del MainFragment:

 getParentFragment().getLoaderManager().initLoader(0, null, this); 
  • ¿Cómo puedo poner títulos en ViewPager usando fragmentos?
  • ¿Cómo puedo establecer una etiqueta para fragmentos de viewpager?
  • Efecto de Cover Flow con ViewPager
  • Preload de la vista del fragmento en ViewPager en la primera ejecución
  • Cómo hacer que mi viewpager pase de derecha a izquierda
  • Gestión del ciclo de vida de Android de Fragmentos dentro de ViewPager y FragmentPagerAdapter
  • ¿Cómo implementar el desplazamiento horizontal dentro de un fragmento?
  • Android ViewPager: fragmentos superpuestos cuando el ancho de página se establece en 90%
  • ¿Dónde está un código de ejemplo / tutorial de Viewpager que funciona bien para todos?
  • ViewPager analógico para paginación a horizontales y verticales
  • Cómo setCurrentPage en ViewPager según la selección del usuario y cómo sé qué artículo de la lista llamó la actividad
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.