添加或删除数据成员时,FragmentPagerAdapter不更新视图位置

时间:2013-02-17 02:29:53

标签: android android-fragments

首次制作FragmentPagerAdapter时,一切都很好。但是,当在某个位置添加或从适配器中删除数据时,视图会保留在它们所处的位置。

Here is a video在我的WIP应用中展示了这个问题,以及我可以用来重现问题的应用的here is an APK。 我的完整代码可以在我的GitHub project上查看。

这是我的适配器代码(也可用here):

public class TaskListFragmentAdapter extends FragmentPagerAdapter {
    private static final String TAG = "TaskListFragmentAdapter";

    public ArrayList<Group> groups;

    /**
     * Fill constructor
     * @param fm The FragmentManager to use
     * @param groups The groups to display
     */
    public TaskListFragmentAdapter(FragmentManager fm, ArrayList<Group> groups) {
        super(fm);
        this.groups = groups;
    }

    /* (non-Javadoc)
     * Gets the fragment at position
     * @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
     */
    @Override
    public TaskListFragment getItem(int position) {
        Log.v(TAG, "Getting item " + position);
        return TaskListFragment.newInstance(groups.get(position));
    }

    /* (non-Javadoc)
     * Gets the position of a fragment
     * @see android.support.v4.view.PagerAdapter#getItemPosition(java.lang.Object)
     */
    @Override
    public int getItemPosition(Object o) {
        TaskListFragment item = (TaskListFragment) o;
        int position = groups.indexOf(item.group);

        if(position >= 0) {
            Log.v(TAG, "Item found at index " + position + ": " + item.group.toString());
            return position;
        } else {
            Log.v(TAG, "Item not found");
            return POSITION_NONE;
        }
    }

    /* (non-Javadoc)
     * Gets the count of fragments
     * @see android.support.v4.view.PagerAdapter#getCount()
     */
    @Override
    public int getCount() {
        return groups.size();
    }

    /* (non-Javadoc)
     * Gets the title of a fragment
     * @see android.support.v4.view.PagerAdapter#getPageTitle(int)
     */
    @Override
    public CharSequence getPageTitle(int position) {
        return groups.get(position).getName();
    }
}

我改变数据的方式很简单;我在活动中有一个groups ArrayList,并使用groups.add(position, item)进行更改。然后活动就是:

adapter.groups = groups;
adapter.notifyDataSetChanged();

更新

我稍微修改了我的代码,并为组添加了正确的.equals()方法,结果发生了一些变化。 当我在开头插入一个组时,getItemPosition现在被调用两次(对于位置1和2),最后两个组视图似乎正在正确更新。然而,添加的和原始的第一个仍未更新。我已更新the APK

以下是在开头插入组并更改数据集时适配器的完整输出:

V/TaskListFragmentAdapter(3597): Item found at index 1: com.gawdl3y.android.tasktimer.classes.Group@b3336038
V/TaskListFragmentAdapter(3597): Item found at index 2: com.gawdl3y.android.tasktimer.classes.Group@b330f330

就是这样。

3 个答案:

答案 0 :(得分:3)

我终于解决了这个问题。我最终做的是从FragmentPagerAdapter切换到FragmentStatePagerAdapter的自定义版本。我的结果代码可以在我的GitHub project看到。相关文件为TaskListFragmentAdapter.javaNewFragmentStatePagerAdapter.java。此自定义版本由UgglyNoodle here创建,并由我自己修改。

答案 1 :(得分:0)

我只是查看了您的来源,我认为问题是您应该在添加新组后刷新任务中的组。 假设你有3个小组,并且在1'你有一些任务(比如视频)。现在,您要在第一个组之前添加一个组,以便它转到列表的第0位。现在您有4个组,并且您的任务仍然将组字段设置为0,因为它们在添加新组之前位于0组并且您没有刷新它。因此,即使ViewPager正在重新创建片段,您的任务也不是您想要的任务。

所以我认为当你添加一个新组并调用reorder(groups)时,你应该创建一个方法来刷新所有任务的task.group字段。

答案 2 :(得分:0)

根据我对您的问题的理解,以及我对您的来源的简要介绍,我认为问题在于您仅在notifyDataSetChanged()上致电FragmentPagerAdapter。但是,您还需要通知您的ViewPager数据集中的此更改。

如果您愿意尝试ViewPager Indicator library,还可以在指标上致电notifyDataSetChanged()。如果没有,我建议您查看此库中TabPageIndicator的代码,看看它是如何实现您正在寻找的效果。