可扩展列表视图重复视图
Expandable List View Duplicate Views
我的问题如下。
我正在实现一个 ExapndableListView,第一组有 children 有一个由这 3 个组成的布局:TextView、ImageView、ImageView。
现在,当单击 child 时,我使用 v.findViewById().setVisibility() 设置了两个图像视图之一的可见性,并且它的工作效果和我想象的一样好。
问题是当列表超过 10 children 时,android 系统在向下滚动时使用顶部最后一个隐藏的视图回收视图,现在当我单击位置“0”的 child ”,我只切换那个视图的图像,而其他视图没有改变,到目前为止还不错,但是当我向下滚动并且 android 系统使用 child“0”视图回收视图child 的位置“11”,它更改了对应于 child“11”的 textView,但用于 child“11”的视图是 child 的视图“0”因此与之前切换的相同图像出现在 child“11”的视图中,就好像它也被点击了,但事实并非如此!
我正在这样做:
@Override
public View getChildView(final int parentPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
Log.d("status","parent : "+parentPosition + " child : " + childPosition + " View : "+convertView + " ViewGroup : "+parent);
int itemType = 25;
itemType = getChildType(parentPosition, childPosition);
String child_title = (String) getChild(parentPosition,childPosition);
if (convertView == null)
{
if (itemType == 0)
{
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.activities2_child_layout, parent, false);
} else if (itemType == 1) {
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.activities2_child2_layout, parent, false);
} else if (itemType == 2) {
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.activities2_child2_layout, parent, false);
}
}
if (itemType == 0)
//region parent 0 child handling
{
Log.d("Child", childPosition + " : " + child_title);
final TextView child_textview = (TextView) convertView.findViewById(R.id.activities2_child_txt);
final ImageView img_Likes = (ImageView) convertView.findViewById(R.id.activities2_img_like);
final ImageView img_Dislikes = (ImageView) convertView.findViewById(R.id.activities2_img_dislike);
child_textview.setText(child_title);
child_textview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (AAChildClicks[childPosition]) {
case 0:
AAChildClicks[childPosition]++;
img_Likes.setVisibility(View.VISIBLE);
//add to total
All_Likes.add(child_textview.getText().toString());
Log.d("Likes", "Likes + " + child_textview.getText().toString());
break;
case 1:
AAChildClicks[childPosition]++;
img_Likes.setVisibility(View.GONE);
img_Dislikes.setVisibility(View.VISIBLE);
String child = child_textview.getText().toString();
//remove from total
All_Likes.remove(child_textview.getText().toString());
Log.d("Likes", "Likes - " + child_textview.getText().toString());
//add to total
All_Dislikes.add(child_textview.getText().toString());
Log.d("Likes", "Dislikes + " + child_textview.getText().toString());
break;
case 2:
AAChildClicks[childPosition] = 0;
img_Likes.setVisibility(View.GONE);
img_Dislikes.setVisibility(View.GONE);
String child2 = child_textview.getText().toString();
//remove from total
All_Dislikes.remove(child_textview.getText().toString());
Log.d("Likes", "Dislikes - " + child_textview.getText().toString());
break;
}
}
});
}
//endregion
if (itemType == 1)
//region parent 1 child handling
{
TextView child_textview = (TextView) convertView.findViewById(R.id.activities2_child2_txt);
child_textview.setText(child_title);
}
//endregion
if (itemType == 2)
//region parent 2 child handling
{
TextView child_textview = (TextView) convertView.findViewById(R.id.activities2_child2_txt);
child_textview.setText(child_title);
}
//endregion
return convertView;
}
如何避免这种情况 duplication/error ?!
目前您将状态存储在 itemView 中 img_Likes.setVisibility(View.VISIBLE);
你也必须将它存储在你的模型中
((MyType) getChild(parentPosition,childPosition)).setIsVisible(true)
如果您(重新)创建列表视图项目,您可以使用该信息来获得(en/dis)可见性
img_Likes.setVisibility((((MyType) getChild(parentPosition,childPosition)).getIsVisible()) ? View.VISIBLE : View.GONE);
当视图被回收时,其组件将保持与之前相同的可见性状态。因此,如果您隐藏了 View 的部分内容,那么当它被回收时,这些部分将被隐藏。
因此,您需要做两件事:
每次调用 GetChildView 时都将视图的可见性设置为正确的状态。
您需要跟踪视图之外的位置数据。现在,您对视图可见性的唯一记录是在视图本身上。当该视图被回收时,您的记录将丢失(视图的状态成为其他位置的起始状态——这就是我们必须在#1 中覆盖它的原因)。
您应该在某种列表或节点类型的体系结构中跟踪视图可见性——您不能将该数据存储在视图上,因为它们不会与任何一个位置永久关联。
我的问题如下。
我正在实现一个 ExapndableListView,第一组有 children 有一个由这 3 个组成的布局:TextView、ImageView、ImageView。
现在,当单击 child 时,我使用 v.findViewById().setVisibility() 设置了两个图像视图之一的可见性,并且它的工作效果和我想象的一样好。
问题是当列表超过 10 children 时,android 系统在向下滚动时使用顶部最后一个隐藏的视图回收视图,现在当我单击位置“0”的 child ”,我只切换那个视图的图像,而其他视图没有改变,到目前为止还不错,但是当我向下滚动并且 android 系统使用 child“0”视图回收视图child 的位置“11”,它更改了对应于 child“11”的 textView,但用于 child“11”的视图是 child 的视图“0”因此与之前切换的相同图像出现在 child“11”的视图中,就好像它也被点击了,但事实并非如此!
我正在这样做:
@Override
public View getChildView(final int parentPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
Log.d("status","parent : "+parentPosition + " child : " + childPosition + " View : "+convertView + " ViewGroup : "+parent);
int itemType = 25;
itemType = getChildType(parentPosition, childPosition);
String child_title = (String) getChild(parentPosition,childPosition);
if (convertView == null)
{
if (itemType == 0)
{
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.activities2_child_layout, parent, false);
} else if (itemType == 1) {
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.activities2_child2_layout, parent, false);
} else if (itemType == 2) {
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.activities2_child2_layout, parent, false);
}
}
if (itemType == 0)
//region parent 0 child handling
{
Log.d("Child", childPosition + " : " + child_title);
final TextView child_textview = (TextView) convertView.findViewById(R.id.activities2_child_txt);
final ImageView img_Likes = (ImageView) convertView.findViewById(R.id.activities2_img_like);
final ImageView img_Dislikes = (ImageView) convertView.findViewById(R.id.activities2_img_dislike);
child_textview.setText(child_title);
child_textview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (AAChildClicks[childPosition]) {
case 0:
AAChildClicks[childPosition]++;
img_Likes.setVisibility(View.VISIBLE);
//add to total
All_Likes.add(child_textview.getText().toString());
Log.d("Likes", "Likes + " + child_textview.getText().toString());
break;
case 1:
AAChildClicks[childPosition]++;
img_Likes.setVisibility(View.GONE);
img_Dislikes.setVisibility(View.VISIBLE);
String child = child_textview.getText().toString();
//remove from total
All_Likes.remove(child_textview.getText().toString());
Log.d("Likes", "Likes - " + child_textview.getText().toString());
//add to total
All_Dislikes.add(child_textview.getText().toString());
Log.d("Likes", "Dislikes + " + child_textview.getText().toString());
break;
case 2:
AAChildClicks[childPosition] = 0;
img_Likes.setVisibility(View.GONE);
img_Dislikes.setVisibility(View.GONE);
String child2 = child_textview.getText().toString();
//remove from total
All_Dislikes.remove(child_textview.getText().toString());
Log.d("Likes", "Dislikes - " + child_textview.getText().toString());
break;
}
}
});
}
//endregion
if (itemType == 1)
//region parent 1 child handling
{
TextView child_textview = (TextView) convertView.findViewById(R.id.activities2_child2_txt);
child_textview.setText(child_title);
}
//endregion
if (itemType == 2)
//region parent 2 child handling
{
TextView child_textview = (TextView) convertView.findViewById(R.id.activities2_child2_txt);
child_textview.setText(child_title);
}
//endregion
return convertView;
}
如何避免这种情况 duplication/error ?!
目前您将状态存储在 itemView 中 img_Likes.setVisibility(View.VISIBLE);
你也必须将它存储在你的模型中
((MyType) getChild(parentPosition,childPosition)).setIsVisible(true)
如果您(重新)创建列表视图项目,您可以使用该信息来获得(en/dis)可见性
img_Likes.setVisibility((((MyType) getChild(parentPosition,childPosition)).getIsVisible()) ? View.VISIBLE : View.GONE);
当视图被回收时,其组件将保持与之前相同的可见性状态。因此,如果您隐藏了 View 的部分内容,那么当它被回收时,这些部分将被隐藏。
因此,您需要做两件事:
每次调用 GetChildView 时都将视图的可见性设置为正确的状态。
您需要跟踪视图之外的位置数据。现在,您对视图可见性的唯一记录是在视图本身上。当该视图被回收时,您的记录将丢失(视图的状态成为其他位置的起始状态——这就是我们必须在#1 中覆盖它的原因)。
您应该在某种列表或节点类型的体系结构中跟踪视图可见性——您不能将该数据存储在视图上,因为它们不会与任何一个位置永久关联。