我无法更新ViewPager中的内容。

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

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

@Override
public Fragment getItem(int position) {
    return new MyFragment(context, paramters);
}

这很有效。但我不能改变内容。

所以我发现这个:ViewPager PagerAdapter没有更新视图

我的方法是对instantiateItem()方法中的任何实例化视图使用setTag()方法

现在我想实现instantiateItem()来实现这一点。但我不知道我必须返回什么(类型是对象)和什么与getItem(int位置)的关系?

我读了参考资料:

public abstract Fragment getItem (int position) Return the Fragment associated with a specified position. public Object instantiateItem (ViewGroup container, int position) Create the page for the given position. The adapter is responsible for adding the view to the container given here, although it only must ensure this is done by the time it returns from finishUpdate(ViewGroup). Parameters container The containing View in which the page will be shown. position The page position to be instantiated. Returns Returns an Object representing the new page. This does not need to be a View, but can be some other container of the page.

但我还是不明白

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

查看页面测试

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);
    }
}

我的片段适配器

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;
    }
}

我的片段

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


当前回答

由于某种原因,没有一个答案对我有用,所以我不得不重写restoreState方法,而不调用我的fragmentStatePagerAdapter中的super。代码:

private class MyAdapter extends FragmentStatePagerAdapter {

    // [Rest of implementation]

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {}

}

其他回答

在代码中的notifyDataSetChanged()之后尝试在ViewPager上销毁drawingcache()。

使用FragmentStatePagerAdapter而不是FragmentPagerAdapter 如果你想在索引基础上重新创建或重新加载片段 例如,如果你想重载FirstFragment以外的fragment,你可以检查instance并返回position,如下所示

 public int getItemPosition(Object item) {
    if(item instanceof FirstFragment){
       return 0;
    }
    return POSITION_NONE;
 }

下面是我的实现,它包含了来自@Bill Phillips的信息 除非数据发生了变化,否则大多数情况下都会使用片段缓存。简单,而且似乎工作得很好。

MyFragmentStatePagerAdapter.java

private boolean mIsUpdating = false;
public void setIsUpdating(boolean mIsUpdating) {
        this.mIsUpdating = mIsUpdating;
    }


@Override
public int getItemPosition(@NonNull Object object) {

    if (mIsUpdating) {
        return POSITION_NONE;
    }
    else {
        return super.getItemPosition(object);
    }
}

MyActivity.java

mAdapter.setIsUpdating(true);
mAdapter.notifyDataSetChanged();
mAdapter.setIsUpdating(false);

如果您想使用FragmentStatePagerAdapter,请查看https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=37990。 FragmentStatePagerAdapter存在一些问题,可能会也可能不会给您的用例带来麻烦。

此外,link也有一些解决方案,少数可能适合您的要求。

I have lived same problem and I have searched too much times. Any answer given in stackoverflow or via google was not solution for my problem. My problem was easy. I have a list, I show this list with viewpager. When I add a new element to head of the list and I refresh the viewpager nothings changed. My final solution was very easy anybody can use. When a new element added to list and want to refresh the list. Firstly set viewpager adapter to null then recreate the adapter and set i to it to viewpager.

myVPager.setAdapter(null);
myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(),newList);
myVPager.setAdapter(myFragmentAdapter);

确保您的适配器必须扩展FragmentStatePagerAdapter