动态更新ViewPager?

6 浏览
0 Comments

动态更新ViewPager?

我无法更新ViewPager中的内容。

在FragmentPagerAdapter类中,instantiateItem()和getItem()方法的正确用法是什么?

我之前只使用getItem()来实例化和返回我的片段:

@Override

public Fragment getItem(int position) {

return new MyFragment(context, parameters);

}

这个方法运行良好,除了我无法更改内容。

所以我找到了这个:ViewPager PagerAdapter not updating the View

引用:

“我在instantiateItem()方法中使用setTag()方法来为任何实例化的视图设置标签”

现在我想实现instantiateItem()来做到这一点,但我不知道我应该返回什么(类型是Object),以及它与getItem(int position)有什么关系?

我阅读了参考文档

  • public abstract Fragment getItem (int position)

    返回与指定位置相关联的片段。

  • public Object instantiateItem (ViewGroup container, int position)

    为给定的位置创建页面。适配器负责将视图添加到这里给出的容器中,尽管它只需确保在从finishUpdate(ViewGroup)返回时完成此操作。

    参数

    container 将显示页面的容器视图。

    position 要实例化的页面位置。

    返回

    返回表示新页面的对象。这不需要是一个View,而可以是页面的其他容器。

但我仍然不明白。

这是我的代码。我使用的是v4支持包。

ViewPagerTest

public class ViewPagerTest extends FragmentActivity {
    private ViewPager pager;
    private MyFragmentAdapter adapter; 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pager1);
        pager = (ViewPager)findViewById(R.id.slider);
        String[] data = {"page1", "page2", "page3", "page4", "page5", "page6"};
        adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
        pager.setAdapter(adapter);
        ((Button)findViewById(R.id.button)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                reload();
            }
        });
    }
    private void reload() {
        String[] data = {"changed1", "changed2", "changed3", "changed4", "changed5", "changed6"};
        //adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
        adapter.setData(data);
        adapter.notifyDataSetChanged();
        pager.invalidate();
        //pager.setCurrentItem(0);
    }
}

MyFragmentAdapter

class MyFragmentAdapter extends FragmentPagerAdapter {
    private int slideCount;
    private Context context;
    private String[] data;
    public MyFragmentAdapter(FragmentManager fm, int slideCount, Context context, String[] data) {
        super(fm);
        this.slideCount = slideCount;
        this.context = context;
        this.data = data;
    }
    @Override
    public Fragment getItem(int position) {
        return new MyFragment(data[position], context);
    }
    @Override
    public int getCount() {
        return slideCount;
    }
    public void setData(String[] data) {
        this.data = data;
    }
    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

MyFragment

public final class MyFragment extends Fragment {
    private String text;
    public MyFragment(String text, Context context) {
        this.text = text;
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.slide, null);
        ((TextView)view.findViewById(R.id.text)).setText(text);
        return view;
    }
}

这里还有一个类似问题的人,但没有答案

http://www.mail-archive.com/android-developers@googlegroups.com/msg200477.html

0
0 Comments

问题出现的原因是,当作者有一个包含7个片段的ViewPager时,这些片段默认从API服务加载英文内容。但问题是,作者想要从设置活动更改语言,然后在完成设置活动后,希望ViewPager在主活动中刷新片段以匹配用户的语言选择,并且如果用户选择了阿拉伯语,则加载阿拉伯语内容。为了解决这个问题,作者采取了以下方法:

1. 使用FragmentStatePagerAdapter作为适配器。

2. 在MainActivity中重写onResume方法,并进行如下操作:

if (!(mPagerAdapter == null)) {
    mPagerAdapter.notifyDataSetChanged();
}

3. 在mPagerAdapter中重写getItemPosition()方法,并让它返回POSITION_NONE。

public int getItemPosition(Object object) {
    return POSITION_NONE;
}

这样做可以使ViewPager的片段刷新以适应语言选择。但有一个特殊情况例外,当在ViewPager中删除最后一个项目时,它不会从列表中移除。另外,作者在ViewPager中动态地向当前片段的左右两侧添加了片段,这也解决了问题。

0
0 Comments

问题:如何动态更新ViewPager?

原因:原来的实现中,在getItemPosition()方法中返回POSITION_NONE,导致ViewPager需要重新创建所有的视图。这样会导致性能问题,因为每次更新都会重新创建所有的fragment。

解决方法:

1. 创建一个UpdateableFragment接口,让所有的fragment实现该接口。

2. 在ViewPager的适配器中,重写getItemPosition()方法,判断传入的object是否是UpdateableFragment的实例,如果是,则调用该fragment的update方法。

3. 在update方法中,根据传入的数据进行UI的更新。

4. 创建一个UpdateData类,用于传递更新的数据。

实现步骤:

1. 创建一个UpdateableFragment接口,并在其中定义一个update方法。

2. 让所有的fragment实现UpdateableFragment接口,并在update方法中根据传入的数据更新UI。

3. 在ViewPager的适配器中,重写getItemPosition()方法,判断传入的object是否是UpdateableFragment的实例,如果是,则调用该fragment的update方法。

4. 创建一个UpdateData类,用于传递更新的数据。

5. 在需要更新ViewPager的地方,调用update方法,并传入更新的数据。

以上就是实现动态更新ViewPager的方法。通过这种方式,可以避免重新创建所有的fragment,提高性能。

0
0 Comments

问题:如何动态更新ViewPager?

原因:使用FragmentPagerAdapter或FragmentStatePagerAdapter时,最好只使用getItem()方法,不要触碰instantiateItem()方法。PagerAdapter的instantiateItem()-destroyItem()-isViewFromObject()接口是一个底层接口,FragmentPagerAdapter使用该接口来实现更简单的getItem()接口。如果想要切换实际显示的片段,需要避免使用FragmentPagerAdapter,而是使用FragmentStatePagerAdapter。

解决方法:重写getItemPosition()方法。当调用notifyDataSetChanged()方法时,ViewPager会调用其适配器中所有项的getItemPosition()方法,以查看它们是否需要移动到其他位置或移除。默认情况下,getItemPosition()方法返回POSITION_UNCHANGED,表示“该对象的位置还可以,不需要销毁或移除”。返回POSITION_NONE可以解决问题,表示“该对象不再是我所显示的项,移除它”。这相当于在适配器中移除并重新创建每个项。这是一个完全合理的解决方法!如果实现了这个修复方法并且性能令人满意,问题就解决了。如果需要更好的性能,可以使用更复杂的getItemPosition()实现。

这篇文章总结了在使用ViewPager动态更新时的问题和解决方法。

0