onResume() nicht aufgerufen, auf ViewPager fragment bei Verwendung von custom Loader
Kurze version:
Habe ich ein fragment, das unterhält eine ViewPager
für die Anzeige von zwei anderen Fragmenten, nennen wir Sie FragmentOne
und FragmentTwo
. Beim starten der app FragmentOne
sichtbar ist und die FragmentTwo
ist off-screen, sichtbar nur wie man klaut Sie die Ansicht auf der linken Seite.
Normalerweise onStart()
und onResume()
get aufgerufen, sofort für beide Fragmente, sobald die app gestartet wird.
Das problem das ich habe ist, wenn FragmentOne
startet eine benutzerdefinierte Loader
dann onResume()
nicht aufgerufen FragmentTwo
bis es vollständig sichtbar ist.
Fragen:
Ist das ein problem mit meinem code oder ist das ein bug in der Android-Support-Library? (Hab das problem nicht auftreten, mit der revision 12 die Bibliothek, es begann mit der revision 13.)
Ob es ein bug in der revisons 13 und 18, gibt es eine Abhilfe?
Gibt es etwas falsch mit meinem custom Loader
?
Lange version:
Ich gebaut habe, eine Beispiel-Anwendung, die das problem veranschaulicht. Ich habe versucht zu reduzieren, den code auf das absolute minimum, aber es ist immer noch viel, also bitte Geduld mit mir.
Ich habe eine MainActivity
lädt ein MainFragment
schafft einen ViewPager
. Es ist wichtig für meine app, die der ViewPager wird betreut durch ein Fragment anstelle der Aktivität.
MainFragment
schafft eine FragmentPagerAdapter
wiederum erzeugt, die die Fragmente FragmentOne
und FragmentTwo
.
Beginnen wir mit dem interessanten etwas, das zwei Fragmente:
FragmentOne
ist ein ListFragment
verwendet eine benutzerdefinierte Loader
zum laden der Inhalte:
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");
}
}
}
Ist es, dass Loader
scheint das problem verursachen. Auskommentieren der initLoader Linie macht die fragment-Lebenszyklus wie erwartet funktioniert wieder.
FragmentTwo
änderungen Ihrer Inhalte auf der Grundlage, ob onResume()
aufgerufen wurde oder nicht:
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");
}
}
Und hier ist der langweilige rest des Codes.
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();
}
}
}
Layout 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" />
Du musst angemeldet sein, um einen Kommentar abzugeben.
Scheint es ein bug in der Bibliothek unterstützt. Die änderung unten löst das Problem.
Anderen workaround, der für mich arbeitete, war der Einsatz der MainFragment loader manager: