【问题标题】:Fragments and FragmentPagerStateAdapter - recreation of views with same id failsFragments 和 FragmentPagerStateAdapter - 重新创建具有相同 ID 的视图失败
【发布时间】:2013-12-10 15:18:02
【问题描述】:

我正在使用 ViewPagerFragmentPagerStateAdapter。每个页面都有一个手动管理的列表 => 我通过从 xml 扩展布局来为这些行创建视图。结果,不同行中的视图具有相同的 id。因为这些行是从 XML 膨胀而来的......

现在的行为如下:

第 1 页如下所示:

// Page 1:
// Row 1: EditText = "Test1" 
// Row 2: EditText = "Test2"

我滑到第 2 页,然后滑到第 3 页,然后我滑回第 1 页,第 1 页如下所示:

// Page 1:
// Row 1: EditText = "Test2" 
// Row 2: EditText = "Test2"

问题:所有 EditText 都显示列表中 lastEditText 的值...(注意,EditText 具有相同的 ID)。

如果我手动将 EditTexts 的 ID 设置为行索引,一切正常。

这正常吗?这个问题有简单(好的)解决方案吗?

【问题讨论】:

  • 请在片段页面 1 上发布列表适配器的代码。
  • 抱歉,没有看到我的更新没有保存...我没有使用适配器...我手动完成所有操作...附加活动后,我更新了我的视图.我从列表中删除所有现有行并添加新行...

标签: android fragment fragmentpageradapter


【解决方案1】:

Tt 似乎是 Android 3.X 中的一个错误

解决方案是手动设置 ID,这样它们就不会在 Fragment 之间匹配或在 Fragment 变得不可见时重置 id。 我喜欢第二个,因为它可以轻松禁用或启用,并且不需要特殊的 id 处理。

/**
 * Used for resetting and restoring View id's. This is used as a workaround for
 * Android 3.x when ViewPager Fragment instances with the same layout have
 * problems referencing next focus id's.
 */
public final class ViewIdResetter {

    private final Map<View, Integer> viewMap;

    public ViewIdResetter(final View rootView) {
        this.viewMap = new HashMap<View, Integer>();
        this.fillmap(rootView);
    }

    private void fillmap(final View view) {
        if (view instanceof ViewGroup) {
            final ViewGroup vg = (ViewGroup) view;
            for (int i = 0; i < vg.getChildCount(); i++) {
                this.fillmap(vg.getChildAt(i));
            }
        }
        this.viewMap.put(view, view.getId());
    }

    public void clearIds() {
        for (final View key : this.viewMap.keySet()) {
            key.setId(-1);
        }
    }

    public void restoreIds() {
        for (final View key : this.viewMap.keySet()) {
            key.setId(this.viewMap.get(key));
        }
    }

}

片段

private ViewIdResetter resetter;

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    this.resetter = new ViewIdResetter(view);
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        if (this.resetter != null) {
            this.resetter.restoreIds();
        }
    } else {
        if (this.resetter != null) {
            this.resetter.clearIds();
        }
    }
}

setUserVisibleHint 在 Fragment 可见时由 ViewPager 触发。 ViewIdResetter 确保一次只有一个 Fragment 具有相同的 id 集。

【讨论】:

  • 这似乎是一个很好的解决方案...我唯一的问题是,您正在引用 android 3.X...我正在我的 4.1 系统上尝试我的应用程序并获得此行为.. . 那么这个错误也是他们的问题还是我的问题必须是另一个问题?
  • 我在 4.x 中没有遇到这个错误。但是我的用例被破坏了 nextFocusLeft() 和 etc 引用,但是数据我没有问题。你可以试试这个 - 如果没有人有更好的想法,它很容易集成并判断是否已修复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-09
  • 1970-01-01
  • 2012-06-12
  • 1970-01-01
  • 2014-03-21
  • 2019-10-28
  • 1970-01-01
相关资源
最近更新 更多