我正在使用ViewPager
FragmentPagerStateAdapter
。每个页面都有一个列表,手动管理=>我通过从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"
问题:所有EditTexts都显示列表中lastEditText的值...(注意,EditTexts具有相同的ID)。
如果我手动将EditTexts的id设置为行索引,一切正常。
这是正常的吗?这个问题有一个简单(好)的解决方案吗?
答案 0 :(得分:1)
Tt似乎是Android 3.X中的一个错误
解决方案是手动设置ID,因此当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();
}
}
}
当片段变为可见时,ViewPager会触发setUserVisibleHint。 ViewIdResetter确保一次只有一个Fragment具有相同的id。