Tôi có 6 trang trong số ViewPager
và OffscreenPageLimit=2
(dễ tái tạo lỗi của mình).
tất cả dữ liệu trong 6 trang là từ máy chủ. Trong onCreateView
, tôi gửi yêu cầu tới máy chủ và làm mới giao diện người dùng khi tôi nhận dữ liệu từ máy chủ.Phân đoạn tạo/khôi phục chế độ xem trùng lặp khi đính kèm lại
Khi tôi chọn tab đầu tiên và thay đổi để kéo dài nhanh chóng nhiều lần, một số máy nhắn tin hiển thị sai. Và tại thời điểm đó, trường của tôi mMainLayout
trong phân đoạn không phải là rỗng. Ví dụ, tôi có một ListView
trong trang đầu tiên của tôi. Khi trang sai, Danh sách xem khác nằm ở trên cùng bên phải Chế độ xem danh sách. Khi tôi cố gắng di chuyển ListView, chỉ di chuyển bên phải (phần dưới).
Tôi biết rằng người nghe phản ứng của tôi giữ tham chiếu của mMainLayout và một số quan điểm khác, tôi tạo ra một mới mMainLayout trong phương pháp onCreateView, tôi nghĩ đoạn sử dụng mới mMainLayout khi nó lại đính kèm/khôi phục và thả cái cũ (hoặc loại bỏ nó khỏi thùng chứa). Nhưng tôi đã sai.
Tôi biết rằng FragmentPagerAdapter
đính kèm/đính kèm lại đoạn trong instantiateItem
và tách ra trong destroyItem
. Bộ điều hợp không xóa một đoạn. Bộ điều hợp không tạo ra một đoạn mới. Fragment giữ chế độ xem và xem trạng thái của chính nó.
Tôi xóa mMainLayout khỏi vùng chứa và đặt tất cả chế độ xem trong phân đoạn rỗng của tôi tại onDestroyView
và không lưu gì trong onSaveInstanceState
. Nhưng vẫn dễ tái tạo lỗi.
hoạt động:
@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();
}
}
đoạn:
@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;
}
Tôi tìm thấy điều này:
Android fragment onCreateView creating duplicate views on top of each other
Nhưng tôi chỉ tạo đoạn mới trong FragmentPagerAdapter.getItem
. Vì vậy, chúng tôi khác nhau.
tôi giải quyết việc này bằng cách loại bỏ tất cả các trẻ em của mMainLayout nếu mMainLayout không phải là null trong phương pháp onCreateView. Sau đó, mọi thứ đều ổn. Nhưng tôi vẫn còn bối rối là tại sao lỗi này lại xảy ra?
Tôi đã thực hiện một số thử nghiệm.
1. cố gắng thêm một đoạn hai lần, lỗi ứng dụng và nhật ký cho biết: java.lang.IllegalStateException: Phân đoạn đã được thêm: ...
2.cố đính kèm một đoạn hai lần, hệ thống không gọi Fragment.onCreate
hoặc Fragment.onCreateView
Vui lòng thêm mã của bạn –
sử dụng 'setRetainInstance (true)' api of fragment Nếu bạn muốn giữ nguyên trạng thái phân đoạn của mình. Khi tải cùng một đoạn 2 lần, nó sẽ tải thành phần giao diện người dùng từ phiên bản trước nếu nó là của chúng trong bộ nhớ khác, đoạn mới sẽ được tạo. Vì vậy, bạn không cần phải làm cho tất cả các thành phần UI null trong phương thức ondestroyview. –
@ keyur9779 Tôi không muốn giữ lại trạng thái phân đoạn của mình. nhưng có vẻ như mảnh đó vẫn khôi phục trạng thái từ trước đó. –