Android 更改已可见TextView的文本时,ListView中的第一项不会更新
我有一个ListView,它由我的自定义BaseAdapter填充,其中的视图包含两个TextView和ImageButton。如果用户从其中一个列表项的弹出菜单中选择一个项,则会更改该列表项上关联文本视图的文本。这对于我的ListView中的所有项目都非常有效,除了第一个项目。由于某些原因,第一项从不更新TextView。我怀疑这与我的convertView没有重置该项有关,但我不确定如何着手修复它 这是我的设置。我有一个由自定义BaseAdapter填充的ListView。在我的BaseAdapter中,我的Android 更改已可见TextView的文本时,ListView中的第一项不会更新,android,listview,baseadapter,Android,Listview,Baseadapter,我有一个ListView,它由我的自定义BaseAdapter填充,其中的视图包含两个TextView和ImageButton。如果用户从其中一个列表项的弹出菜单中选择一个项,则会更改该列表项上关联文本视图的文本。这对于我的ListView中的所有项目都非常有效,除了第一个项目。由于某些原因,第一项从不更新TextView。我怀疑这与我的convertView没有重置该项有关,但我不确定如何着手修复它 这是我的设置。我有一个由自定义BaseAdapter填充的ListView。在我的BaseAd
getView()
中有这个:
IMOModGroup是一种特殊的数据结构,它保存每个列表项的所有状态和数据。因此,当convertView为null时,BaseAdapter会从IMOModGroup请求一个新的convertView以用于该位置。以下是创建新convertView的IMOModGroup方法:
public View getConvertView(ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.modifier_list_item, parent, false);
//...
TextView selectedModText = (TextView) convertView.findViewById(R.id.modName);
selectedModText.setText(R.string.no_modifier_selected);
selectedModText.setTextColor(context.getResources().getColor(R.color.grayed_out_text_color));
//...
return convertView;
}
用户可以在每个列表项上打开弹出菜单并进行选择。当他们这样做时,上述代码中的TextView将被更改,以用新文本反映所选内容。该代码如下所示:
public boolean onMenuItemClick(MenuItem item) {
String selectedMod = item.getTitle().toString();
TextView selectedModText = (TextView) convertView.findViewById(R.id.modName);
selectedModText.setText(selectedMod);
selectedModText.setTextColor(context.getResources().getColor(R.color.imo_blue_light));
//...
return false;
}
所有这些在ListView中的每一项上都非常有效,除了第一项,它从不更新以反映TextView的更改。我已经进行了测试,以确保TextView文本实际上正在更改,可以在以后调用和查看,并且设置正确。所以看起来数据是正确的,但是视图没有得到更新
我很确定问题在于我的convertView没有被重置,所以ListView只是继续使用旧视图和旧文本。设置文本后,我尝试在BaseAdapter上调用notifyDataSetChanged()
,但没有成功
这个问题看起来很有希望:
但我不确定这是否是我的问题,我也不确定如何将其应用到我的场景中
有什么想法吗?我已经通读了一些关于SO和Google的类似问题,但没有一个与我的具体情况相关。我已经使用ListView和Adapters很长一段时间了,这是我第一次看到这样的东西。谢谢你的帮助
根据评论进行编辑 下面是完整的BaseAdapter代码
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.ArrayList;
public class IMOModListAdapter extends BaseAdapter {
private Context context;
private ArrayList<IMOModGroup> modGroups;
public IMOModListAdapter(Context context, ArrayList<IMOModGroup> modGroups) {
this.context = context;
this.modGroups = modGroups;
}
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
IMOModGroup modGroup = modGroups.get(position);
convertView = modGroup.getConvertView(parent);
}
return convertView;
}
public Object getItem(int position) {
return 0;
}
public long getItemId(int position) {
return 0;
}
public int getCount() {
return modGroups.size();
}
}
我找到了解决这个问题的办法。在研究有关BaseAdapters和
getView()
的随机问题时,我终于遇到了一个问题,他在问题中指出,对于ListView的layout\u height
,永远不要使用wrap\u content
,因为它会导致ListView调用适配器的getView()
创建虚拟视图(用于测量内容高度)需要花费大量时间。原来这是导致我的问题的原因,所以将我的布局\u高度
更改为匹配\u父项
就成功了
不幸的是,现在这导致了一个新问题,因为我无法使用匹配父视图
,因为它将隐藏父布局中的其他视图。但至少第一个列表项现在正在正确更新
更新: 我学习了如何在填充ListView的适配器后手动动态设置其高度。我使用了下面的方法,希望这能帮助一些遇到类似问题的人。这使得我不必使用
wrap\u content
,但我仍然可以将ListView
高度设置为仅与其内容一样大
private void setModListHeight() {
int numberOfItems = modGroups.size(); //the ArrayList providing data for my ListView
int totalItemsHeight = 0;
for(int position = 0; position < numberOfItems; position++) {
View item = modListAdapter.getView(position, null, modList);
item.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
totalItemsHeight += item.getMeasuredHeight();
}
int totalDividersHeight = modList.getDividerHeight() * (numberOfItems - 1);
ViewGroup.LayoutParams params = modList.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight;
modList.setLayoutParams(params);
modList.requestLayout();
}
private void setModListHeight(){
int numberOfItems=modGroups.size();//为我的ListView提供数据的ArrayList
int totalItemsHight=0;
对于(int position=0;position
尝试移动IMOModGroup=modGroups.get(位置)代码>脱离if Block能否显示整个适配器类?@SebastianRoth-发布了完整的BaseAdapter代码。@mdtuyen-不能这样做,因为无论发生什么情况,每次我都会得到一个新的convertView实例。只是为了好玩,我试了一下,结果它表现得和我预期的一样,而且没有正常工作。
//Set the text of the first item. This does NOTHING and the TextView
//in the item remains unchanged
IMOModGroup modGroup = modGroups.get(0);
modGroup.setTestText("This is some test text");
modList.notifyDataSetChanged();
//Set the text of the second item. This works completely fine!!!!!
IMOModGroup modGroup = modGroups.get(1);
modGroup.setTestText("This is some test text");
modList.notifyDataSetChanged();
private void setModListHeight() {
int numberOfItems = modGroups.size(); //the ArrayList providing data for my ListView
int totalItemsHeight = 0;
for(int position = 0; position < numberOfItems; position++) {
View item = modListAdapter.getView(position, null, modList);
item.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
totalItemsHeight += item.getMeasuredHeight();
}
int totalDividersHeight = modList.getDividerHeight() * (numberOfItems - 1);
ViewGroup.LayoutParams params = modList.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight;
modList.setLayoutParams(params);
modList.requestLayout();
}