我使用viewpager来显示图片。我基本上只需要三个片段:前一个要预览的图像,当前的显示图像和下一个要预览的图像。我想只显示上一张和下一张图片的预览,当用户实际滑动到它时,它会变为完整图像。所以我想到只使用3个片段来实现这一目标。代码如下:
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()来使用户滑动到新页面时更新片段的所有三个位置。
但问题是它会抛出
Fragment already added IllegalStateException
第二次添加片段时。我认为这是因为它之前被添加过了。我每次都可以创建一个新片段,但我觉得这很浪费。那么如何重用已经创建的片段并更新它们呢?
谢谢, 西蒙
答案 0 :(得分:3)
FragmentStatePagerAdapter
设计建议为每个页面see Google's example创建一个新的Fragment
。不幸的是,一旦将Fragment
添加到FragmentManager
(适配器内隐含的内容),您就无法读取PagerAdapter
,因此您将面临例外。所以官方的谷歌方式是创建新的片段,让它们被适配器销毁和重新创建。
但是如果你想重用页面并使用ViewHolder模式的模拟,你应该坚持使用视图而不是片段。与片段不同,视图可以从其父级中删除并重用。像这样扩展instantiateItem()
并实施@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;
}
:
drop_persona1.Items.Clear();
string valor = drop_area.SelectedValue;
List<string> allUsers = new List<string>();
PrincipalContext ctx2 = new PrincipalContext(ContextType.Domain, "xxxxxxxx",
valor);
UserPrincipal qbeUser2 = new UserPrincipal(ctx2);
qbeUser2.Enabled = true; // activo para autenticacion
PrincipalSearcher srch2 = new PrincipalSearcher(qbeUser2);
srch2.QueryFilter = qbeUser2;
foreach (var found2 in srch2.FindAll().OrderBy(x=> x.DisplayName))
{
ListItem lst_user = new ListItem(found2.DisplayName, found2.SamAccountName);
drop_persona1.Items.Insert(drop_persona1.Items.Count, lst_user);
}
//}
}
您应该添加一些额外的逻辑来按位置确定视图类型(因为您有3种类型的视图),我想您可以解决这个问题。