Ich habe 6 Seiten in meinem ViewPager
und OffscreenPageLimit=2
(einfach meinen Fehler zu reproduzieren).
Alle Daten auf den 6 Seiten stammen vom Server. In onCreateView
, ich sende eine Anfrage an den Server, und UI aktualisieren, wenn ich Daten vom Server bekomme.Fragment Erstellen/Wiederherstellen einer doppelten Ansicht beim erneuten Anfügen
Wenn ich die erste Registerkarte wähle und mehrmals schnell hintereinander wechsle, werden einige Pager falsch angezeigt. Und zu diesem Zeitpunkt ist mein Feld mMainLayout
im Fragment nicht null.
Zum Beispiel habe ich eine ListView
in meiner ersten Seite. Wenn die Seite falsch ist, ist ein weiterer ListView oben rechts ListView. Wenn ich versuche, ListView zu scrollen, wird nur die rechte (untere) verschoben.
Ich weiß, dass meine Antwort Zuhörer Bezug von mMainLayout hält und einige andere Ansichten, ich erstellen Sie eine neue mMainLayout in Methode onCreateView, dachte ich Fragment neu verwenden mMainLayout, wenn es wieder anbringen/Restore und lasse die alte fallen (oder entferne sie aus dem Container). Aber ich habe mich getäuscht.
Ich weiß, dass FragmentPagerAdapter
Fragment in instantiateItem
anfügen/erneut anfügen und in destroyItem
lösen. Adapter hat kein Fragment entfernt. Adapter hat kein neues Fragment erstellt. Fragment behalten Sie den Blick und sehen Sie sich selbst an.
I mMainLayout aus dem Behälter entfernen und alle Ansichten in meinem Fragmente null auf onDestroyView
gesetzt und nichts in onSaveInstanceState
speichern. Aber immer noch einfach den Fehler zu reproduzieren.
Aktivität:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
registerReceiver(receiver, new IntentFilter("com.souyidai.intent.action.log_fragment"));
FragmentManager fragmentManager = getFragmentManager();
mResources = getResources();
mMainPagerAdapter = new MainPagerAdapter(fragmentManager);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mMainPagerAdapter);
mPager.setOffscreenPageLimit(CACHE_SIZE);
mIndicator = (TabPageIndicator) findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
...
}
private class MainPagerAdapter extends FragmentPagerAdapter {
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
MainConfig.TabItem tab = mTabs.get(position);
String tabType = tab.getTabType();
String code = tab.getCode();
MainConfig.TabItem.SubTabItem subTabItem = tab.getSubitem().get(0);
Fragment fragment = MainFragment.newInstance(code, subTabItem);
return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
MainConfig.TabItem tab = mTabs.get(position);
return tab.getTitle();
}
@Override
public int getCount() {
return mTabs.size();
}
}
Fragment:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContainer = container;
mMainLayout = inflater.inflate(R.layout.fragment_main, container, false);
...
}
@Override
public void onDestroyView() {
super.onDestroyView();
mContainer.removeView(mMainLayout);
mContainer = null;
mMainLayout = null;
mSwipeRefreshLayout = null;
mListView = null;
mHeaderLayout = null;
mFooterLayout = null;
...
}
android.support.v13.app.FragmentPagerAdapter
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
final long itemId = getItemId(position);
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
}
if (fragment != mCurrentPrimaryItem) {
FragmentCompat.setMenuVisibility(fragment, false);
FragmentCompat.setUserVisibleHint(fragment, false);
}
return fragment;
}
ich diese finden:
Android fragment onCreateView creating duplicate views on top of each other
Aber ich erstelle nur neue Fragment in FragmentPagerAdapter.getItem
. Also sind wir anders.
Ich löse dies, indem alle Kinder von Entfernen mMainLayout wenn mMainLayout nicht null in Methode ist onCreateView. Dann ist alles in Ordnung. Aber ich bin immer noch verwirrt, warum dieser Fehler passiert?
Ich habe einige Tests gemacht.
1. Versuchen Sie, ein Fragment zweimal hinzuzufügen, app crash und log sagt: java.lang.IllegalStateException: Fragment bereits hinzugefügt: ...
2.versuchen, ein Fragment zweimal zu befestigen, System nicht Fragment.onCreate
oder Fragment.onCreateView
ruft
Fügen Sie bitte Ihren Code hinzu –
Verwenden Sie 'setRetainInstance (true)' api des Fragments Wenn Sie Ihren Fragmentstatus beibehalten möchten. Beim zweiten Laden desselben Fragments wird die UI-Komponente von der vorherigen Instanz geladen, wenn sie im Speicher ist. Andernfalls wird ein neues Fragment erstellt. Sie müssen also nicht alle UI-Komponenten in der ondestroyview-Methode null machen. –
@ keyur9779 Ich möchte meine Fragment-Zustände nicht beibehalten. aber es sieht so aus, als ob dieses Fragment noch immer den vorherigen Zustand wiederherstellt. –