在Android Listview中设置行背景时出现问题
我有一个应用程序,我希望一次一行有一种特定的颜色。这似乎在95%的情况下都能正常工作,但有时它会允许多行使用此颜色,而不是只有一行使用此颜色。具体来说,一行被设置为在点击时具有“特殊”颜色。在极少数情况下,尽管调用setBackgroundColor试图使最后一行保留颜色,但最后一行仍将保留该颜色在Android Listview中设置行背景时出现问题,android,listview,Android,Listview,我有一个应用程序,我希望一次一行有一种特定的颜色。这似乎在95%的情况下都能正常工作,但有时它会允许多行使用此颜色,而不是只有一行使用此颜色。具体来说,一行被设置为在点击时具有“特殊”颜色。在极少数情况下,尽管调用setBackgroundColor试图使最后一行保留颜色,但最后一行仍将保留该颜色 private OnItemClickListener mDirectoryListener = new OnItemClickListener(){ public void onItemCl
private OnItemClickListener mDirectoryListener = new OnItemClickListener(){
public void onItemClick(AdapterView parent, View view, int pos, long id){
if (stdir.getStationCount() == pos) {
stdir.moreStations();
return;
}
if (playingView != null)
playingView.setBackgroundColor(Color.DKGRAY);
view.setBackgroundColor(Color.MAGENTA);
playingView = view;
playStation(pos);
}
};
我已经用print语句确认,总是调用将行设置为灰色的代码
有人能想象这段代码可能间歇性失败的原因吗?如果有一个模式或条件导致它,我不能说
我认为这可能与活动生命周期有关,将“playingView”变量设置回null,但我无法通过切换活动或锁定手机来可靠地重现问题
private class DirectoryAdapter extends ArrayAdapter {
private ArrayList<Station> items;
public DirectoryAdapter(Context c, int resLayoutId, ArrayList<Station> stations){
super(c, resLayoutId, stations);
this.items = stations;
}
public int getCount(){
return items.size() + 1;
}
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (position == this.items.size()) {
v = vi.inflate(R.layout.morerow, null);
return v;
}
Station station = this.items.get(position);
v = vi.inflate(R.layout.songrow, null);
if (station.playing)
v.setBackgroundColor(Color.MAGENTA);
else if (station.visited)
v.setBackgroundColor(Color.DKGRAY);
else
v.setBackgroundColor(Color.BLACK);
TextView title = (TextView)v.findViewById(R.id.title);
title.setText(station.name);
return v;
}
};
私有类目录适配器扩展了ArrayAdapter{
私有ArrayList项;
public DirectoryAdapter(上下文c、int-resLayoutId、ArrayList站){
超级(c、重新布局、车站);
此项=站点;
}
public int getCount(){
返回项目。大小()+1;
}
公共视图getView(int位置、视图转换视图、视图组父视图){
视图v=转换视图;
LayoutInflater vi=(LayoutInflater)getContext().getSystemService(Context.LAYOUT\u INFLATER\u SERVICE);
if(position==this.items.size()){
v=vi.充气(R.layout.morerow,空);
返回v;
}
Station Station=此.items.get(位置);
v=vi.充气(R.布局.松罗,空);
如果(电台播放)
v、 挫折背景色(颜色:洋红色);
else if(已访问的站点)
v、 setBackgroundColor(颜色:灰色);
其他的
v、 setBackgroundColor(颜色:黑色);
TextView title=(TextView)v.findViewById(R.id.title);
title.setText(站名);
返回v;
}
};
ListView不会为列表中的每个项目创建包含视图的实例,而只为屏幕上实际可见的项目创建包含视图的实例。出于性能方面的原因,他们会尝试维护尽可能少的视图,并回收它们。这就是convertView参数
当视图从屏幕上滚下时,它可能会被回收或销毁。您不能持有对旧视图的引用,并假设它将引用您希望它将来引用的项。您应该保存所需列表项的ID,然后查找它
此外,您的实现还存在一些其他问题(从最佳实践的角度来看)。您似乎忽略了convertView参数,每次都从头开始创建一个新视图。如果列表很长,则在滚动时可能会导致应用程序有点停滞。其次,与其像您那样添加“more”元素,不如使用setFooterView()进行设置
谷歌I/O 2010发布了一份报告,涵盖了这些问题和其他问题。它有一个小时长,但绝对值得完整观看。我打赌当你滚动
时会发生这种情况。我确信在onItemClick中设置bg颜色后,@zchtodd没有在ListAdapter中重置颜色。。如果可能,从适配器发布getView()。@varun,我正在其他地方更改电台的“播放”属性,但将该代码移动到上面的OnItemClick块以确保其处于正确的状态并没有改变任何内容。我假设您在调用playStation(pos)时设置了播放
属性在mclick中选择code>。您应该将上一电台的播放设置为false。我认为您缺少了一些小东西。我已经删除了对Radio类中视图的所有引用,现在调用invalidateRows()来强制重新绘制ListView。这会产生正确的行为。如果我尝试使用我跟踪的ID从listview获取视图,我应该调用什么函数?调用getView()似乎不正确。若要获取现有视图,请使用ListView.getChildAt()