【发布时间】:2015-07-06 17:24:52
【问题描述】:
我在详细视图中使用 ViewPager 和 FragmentPagerAdapter。这意味着我有一个项目列表,一个屏幕显示单个项目的详细信息。但是用户可以左右滑动来浏览所有项目。这遵循谷歌guideline for swiping views。
但我想知道一件事。在 ListView 中,每一行的视图都会被重用。一旦一行滚动出屏幕,它将被重新用作绑定到适配器的 getView 方法的 convertView 参数列表视图。但是这种重用行为似乎并没有为滑动视图实现。这个例子说明了这一点:
class DemoAdapter extends ArrayAdapter<DemoItem> {
public DemoAdapter(Context context, List<DemoItem> objects) {
super(context, 0, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
// create a new view, otherwise re-use the existing convertView
LayoutInflater i = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = i.inflate(R.layout.list_item_demo, parent, false);
}
// get current item
DemoItem item = getItem(position);
if (item == null)
return convertView;
// update view with the item
TextView textTitle = (TextView)convertView.findViewById(R.id.demo_title);
if (textTitle != null)
textTitle.setText(item.getTitle());
return convertView;
}
}
但问题出在这里: FragmentPagerAdapter 和 FragmentStatePagerAdapter 都在创建片段(每个屏幕都是一个片段)他们的 getItem 方法。但他们不会将旧片段作为输入参数。唯一的区别是,FragmentStatePagerAdapter 会销毁未使用的片段。
public class DemoItemsPagerAdapter extends FragmentPagerAdapter {
private final Context context;
public DemoItemsPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
// ToDo: get cursor or array of available items that can be swiped through
}
@Override
public Fragment getItem(int i) {
Fragment fragment = new DemoItemFragment();
// ToDo: initialize fragment by correct item
// ToDo: avoid creating too many fragments - try reusing them (but how?)
return fragment;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// the container is not the fragment, but the ViewPager itself
return super.instantiateItem(container, position);
}
@Override
public CharSequence getPageTitle(int position) {
// ToDo: return name for current entry
return null;
}
@Override
public int getCount() {
// ToDo: get count from cursor/array of available items
return 2;
}
}
那么,我怎样才能重用片段? 实际上,getItems 应该只调用两次,因为一次只有一个片段可见,而在用户滑动时开始转换时,第二个片段可见。
更新:由于混淆,我创建了这张图。它显示了适配器的行为。默认设置将所有片段保存在内存中,除非设备内存不足。一个应用程序在后台或被杀死然后恢复每个片段将从其 SavedInstanceState 恢复。第二种实现只在内存中保留一些片段,但如果你向左/向右滑动,被破坏的片段将完全从头开始重新创建。第三个实现是我正在寻找的。您只有三个片段,然后在向左或向右滑动时会重复使用这些片段。所以片段A可以是位置1、2、3、4、5、6和7。
【问题讨论】:
-
为什么要重用片段?列表视图重用视图,因为这样它就不必一次又一次地膨胀它们,这应该是昂贵的。我个人认为重用视图被高估了。您必须自己编程片段的重用,这是一项不平凡的工作。为什么要打扰?
-
因为每个页面看起来都一模一样,而膨胀布局确实是一项昂贵的操作。
标签: android android-fragments android-viewpager fragmentpageradapter