片段已经在viewpager中添加了IllegalStateException [英] Fragment already added IllegalStateException in viewpager
问题描述
我正在使用viewpager显示图片.我基本上只需要三个片段:上一个图像进行预览,当前显示图像和下一个图像进行预览.我只想显示上一张和下一张图像的预览,当用户实际滑动到它时,它将变为完整图像.因此,我正在考虑仅使用3个片段来实现这一目标.代码如下:
I'm using viewpager to display pictures. I just need three fragments basically: previous image to preview, current display image and next image to preview. I would like to just display a preview of previous and next image, it will change to full image when user actually swipe to it. So I'm thinking of just using 3 fragment to achieve this. Code is below:
private class ImagePagerAdapter extends FragmentStatePagerAdapter implements ViewPager.OnPageChangeListener {
private ImageFragment mImageFragment;
private ImagePreviewFragment mPreviousPreviewFragment;
private ImagePreviewFragment mNextPreviewFragment;
public ImagePagerAdapter(FragmentManager fm, ImageFragment image, ImagePreviewFragment previous, ImagePreviewFragment next) {
super(fm);
mImageFragment = image;
mPreviousPreviewFragment = previous;
mNextPreviewFragment = next;
}
@Override
public Fragment getItem(int position) {
if (position == mPager.getCurrentItem()) {
mImageFragment.display(position);
return mImageFragment;
}
if (position < mPager.getCurrentItem()) {
mPreviousPreviewFragment.display(position - 1);
return mPreviousPreviewFragment;
}
mNextPreviewFragment.display(position + 1);
return mNextPreviewFragment;
}
@Override
public int getCount() {
return 100;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.d(TAG, "onPageScrolled");
}
@Override
public void onPageSelected(final int position) {
Log.d(TAG, "onPageSelected " + position);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
}, 500);
}
@Override
public void onPageScrollStateChanged(int state) {
Log.d(TAG, "onPageScrollStateChanged " + state);
}
@Override
public int getItemPosition(Object item) {
return POSITION_NONE;
//return POSITION_UNCHANGED;
}
}
因此,基本上,我预先创建了三个片段来显示上一个/下一个预览和当前图像,并将它们返回给getItem().我还在onpageselected()中notifydatasetchange()来使所有三个位置在用户滑动到新页面时更新片段.
So basically, I pre-created three fragments to display previous/next preview and current image and return them for getItem(). I also notifydatasetchange() in onpageselected() to make all three position to update the fragment when user swipe to new page.
但是问题在于它会扔掉
Fragment already added IllegalStateException
第二次添加片段时.我认为这是因为它是以前添加的.我每次都可以创建一个新片段,但这很浪费.那么如何重用已经创建的片段并更新它们呢?
when the fragments are added a second time. I think it's because it's been added before. I can create a new fragment every time but I think that's wasteful. So how can I reuse the already created fragment and just update them?
谢谢, 西蒙
推荐答案
FragmentStatePagerAdapter
设计建议为每个页面创建一个新的Fragment
(
FragmentStatePagerAdapter
design suggests creating a new Fragment
for every page (see Google's example). And unfortunately you cannot readd a Fragment
once it was added to a FragmentManager
(what implicitly happens inside adapter), hence the exception you got. So the official Google-way is to create new fragments and let them be destroyed and recreated by the adapter.
但是,如果您想重用页面并利用ViewHolder模式的类似物,则应该坚持使用视图而不是片段.与片段不同,可以将视图从其父视图中删除并重新使用.扩展PagerAdapter
并像这样实现instantiateItem()
:
But if you want to reuse pages and utilize an analogue of ViewHolder pattern, you should stick to views instead of fragments. Views could be removed from their parent and reused, unlike fragments. Extend PagerAdapter
and implement instantiateItem()
like this:
@Override
public Object instantiateItem(ViewGroup container, final int position) {
//determine the view type by position
View view = viewPager.findViewWithTag("your_view_type");
if (view == null) {
Context context = container.getContext();
view = LayoutInflater.from(context).inflate(R.layout.page, null);
view.setTag("your_view_type");
} else {
ViewGroup parent = (ViewGroup) item.getParent();
if (parent != null) {
parent.removeView(item);
}
}
processYourView(position, view);
container.addView(view, MATCH);
return view;
}
您应该添加一些额外的逻辑以按位置确定视图类型(因为您有3种视图类型),我想您可以弄清楚这一点.
You should add some extra logic to determine the view type by position (since you have 3 types of views), I think you can figure that out.
这篇关于片段已经在viewpager中添加了IllegalStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!