Android 带有 CustomAdapter 显示工件的 ExpandableListView
Android ExpandableListView with CustomAdapter display artifacts
我遇到了 ExpandableListView
和自定义适配器的错误
看起来 TextView
没有自己的价值,你可以在视频中看到。模型仅在此列表中不更改此值
Name 和phone 不影响,但是两个右边的textview 是。
https://www.youtube.com/embed/YjC_QsA75yo
有人遇到过这个错误吗?
知道如何追踪和修复它吗?
更新
public ExpandableAdapter(List<CategoryModel> categoryModels, Context ctx) {
this.categoryModels = categoryModels;
this.ctx = ctx;
}
@Override
public int getGroupCount() {
return categoryModels.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return categoryModels.get(groupPosition).getMembers().size();
}
@Override
public Object getGroup(int groupPosition) {
return categoryModels.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return categoryModels.get(groupPosition).getMembers().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return categoryModels.get(groupPosition).getId();
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return categoryModels.get(groupPosition).getMembers().get(childPosition).getId();
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.reg_group_layout, parent, false);
}
TextView groupName = (TextView) v.findViewById(R.id.tv_group_name);
TextView groupCount = (TextView) v.findViewById(R.id.tv_group_count);
CategoryModel cat = categoryModels.get(groupPosition);
groupName.setText(cat.toString());
groupCount.setText(cat.getMembers().size() + "");
return v;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.reg_member_layout, parent, false);
}
TextView tvName = (TextView) v.findViewById(R.id.tv_reg_mem_name);
TextView tvPhone = (TextView) v.findViewById(R.id.tv_reg_mem_phone);
TextView tvFinishTime = (TextView) v.findViewById(R.id.tv_reg_finishtime);
TextView tvPenaltyTime = (TextView) v.findViewById(R.id.tv_reg_penaltytime);
MemberModel mem = (MemberModel) getChild(groupPosition, childPosition);
if (!mem.getActive()) {
tvName.setTextColor(Color.GRAY);
tvPhone.setTextColor(Color.GRAY);
} else {
tvName.setTextColor(Color.BLACK);
tvPhone.setTextColor(Color.BLACK);
}
tvName.setText(mem.getMem_name());
tvPhone.setText(mem.getMem_tel());
Util.setFinishTime(tvFinishTime, mem.getFinishTime());
Long penTime = mem.getPenaltyTime();
if (penTime != null && penTime != 0) {
Util.setPenaltyTime(tvPenaltyTime, penTime);
} else {
//tvPenaltyTime.setVisibility(View.INVISIBLE);
}
return v;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
return true;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
super.registerDataSetObserver(observer);
}
确保始终设置 FinishTime 和 Penaltytime,如果为空,甚至设置为空格。
发生了什么事,您得到了 convertViews(旧内容的旧视图),您需要用新内容填充它们。这些行:
if (penTime != null && penTime != 0) {
Util.setPenaltyTime(tvPenaltyTime, penTime);
} else {
//tvPenaltyTime.setVisibility(View.INVISIBLE);
}
如果不为 0 将设置惩罚时间,但如果为 0,则将保留旧视图的旧值,无论它是什么。这就是为什么当有惩罚时间的行退出屏幕时,进入屏幕的新视图将保留旧的惩罚时间(如果没有)。
学习 View Recycling
的工作原理是值得的!您可以通过使用 ViewHolder
和缓存 findViewById's
.
进一步优化您的适配器
所以你可以这样做:
if (penTime != null && penTime != 0) {
Util.setPenaltyTime(tvPenaltyTime, penTime);
} else {
Util.setPenaltyTime(tvPenaltyTime, 0);
}
或者,正如您尝试的那样,
if (penTime != null && penTime != 0) {
Util.setPenaltyTime(tvPenaltyTime, penTime);
tvPenaltyTime.setVisibility(View.VISIBLE);
} else {
tvPenaltyTime.setVisibility(View.INVISIBLE);
}
我遇到了 ExpandableListView
和自定义适配器的错误
看起来 TextView
没有自己的价值,你可以在视频中看到。模型仅在此列表中不更改此值
Name 和phone 不影响,但是两个右边的textview 是。
https://www.youtube.com/embed/YjC_QsA75yo
有人遇到过这个错误吗? 知道如何追踪和修复它吗?
更新
public ExpandableAdapter(List<CategoryModel> categoryModels, Context ctx) {
this.categoryModels = categoryModels;
this.ctx = ctx;
}
@Override
public int getGroupCount() {
return categoryModels.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return categoryModels.get(groupPosition).getMembers().size();
}
@Override
public Object getGroup(int groupPosition) {
return categoryModels.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return categoryModels.get(groupPosition).getMembers().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return categoryModels.get(groupPosition).getId();
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return categoryModels.get(groupPosition).getMembers().get(childPosition).getId();
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.reg_group_layout, parent, false);
}
TextView groupName = (TextView) v.findViewById(R.id.tv_group_name);
TextView groupCount = (TextView) v.findViewById(R.id.tv_group_count);
CategoryModel cat = categoryModels.get(groupPosition);
groupName.setText(cat.toString());
groupCount.setText(cat.getMembers().size() + "");
return v;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.reg_member_layout, parent, false);
}
TextView tvName = (TextView) v.findViewById(R.id.tv_reg_mem_name);
TextView tvPhone = (TextView) v.findViewById(R.id.tv_reg_mem_phone);
TextView tvFinishTime = (TextView) v.findViewById(R.id.tv_reg_finishtime);
TextView tvPenaltyTime = (TextView) v.findViewById(R.id.tv_reg_penaltytime);
MemberModel mem = (MemberModel) getChild(groupPosition, childPosition);
if (!mem.getActive()) {
tvName.setTextColor(Color.GRAY);
tvPhone.setTextColor(Color.GRAY);
} else {
tvName.setTextColor(Color.BLACK);
tvPhone.setTextColor(Color.BLACK);
}
tvName.setText(mem.getMem_name());
tvPhone.setText(mem.getMem_tel());
Util.setFinishTime(tvFinishTime, mem.getFinishTime());
Long penTime = mem.getPenaltyTime();
if (penTime != null && penTime != 0) {
Util.setPenaltyTime(tvPenaltyTime, penTime);
} else {
//tvPenaltyTime.setVisibility(View.INVISIBLE);
}
return v;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
return true;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
super.registerDataSetObserver(observer);
}
确保始终设置 FinishTime 和 Penaltytime,如果为空,甚至设置为空格。
发生了什么事,您得到了 convertViews(旧内容的旧视图),您需要用新内容填充它们。这些行:
if (penTime != null && penTime != 0) {
Util.setPenaltyTime(tvPenaltyTime, penTime);
} else {
//tvPenaltyTime.setVisibility(View.INVISIBLE);
}
如果不为 0 将设置惩罚时间,但如果为 0,则将保留旧视图的旧值,无论它是什么。这就是为什么当有惩罚时间的行退出屏幕时,进入屏幕的新视图将保留旧的惩罚时间(如果没有)。
学习 View Recycling
的工作原理是值得的!您可以通过使用 ViewHolder
和缓存 findViewById's
.
所以你可以这样做:
if (penTime != null && penTime != 0) {
Util.setPenaltyTime(tvPenaltyTime, penTime);
} else {
Util.setPenaltyTime(tvPenaltyTime, 0);
}
或者,正如您尝试的那样,
if (penTime != null && penTime != 0) {
Util.setPenaltyTime(tvPenaltyTime, penTime);
tvPenaltyTime.setVisibility(View.VISIBLE);
} else {
tvPenaltyTime.setVisibility(View.INVISIBLE);
}