1

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

这是在我的 WIP 应用程序中演示该问题的视频,这是我的应用程序的 APK,您可以使用它来重现该问题。我的完整代码可以在我的GitHub 项目中查看。

这是我的适配器代码(也可在此处获得):

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),并且最后两个组视图似乎正在正确更新。但是,添加的那个和原来的第一个仍然没有更新。我已经更新了 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

就是这样。

4

3 回答 3

3

我终于解决了这个问题。我最终做的是FragmentPagerAdapterFragmentStatePagerAdapter. 我的生成代码可以在我的GitHub 项目中看到。相关文件是TaskListFragmentAdapter.javaNewFragmentStatePagerAdapter.java。这个自定义版本是由 UgglyNoodle在这里创建的,我自己进行了修改。

于 2013-02-21T03:47:06.550 回答
0

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

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

于 2013-02-19T07:52:09.410 回答
0

根据我对您的问题的理解,以及对您来源的简要阅读,我认为问题在于您只是在notifyDataSetChanged()呼吁FragmentPagerAdapter。但是,您还需要通知您ViewPager有关数据集中的此更改。

如果您愿意尝试ViewPager Indicator 库,您也可以调用notifyDataSetChanged()指标。如果没有,我建议你查看TabPageIndicator这个库中的代码,看看它是如何达到你想要的效果的。

于 2013-02-20T05:59:24.257 回答