Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Android Listview中设置行背景时出现问题_Android_Listview - Fatal编程技术网

在Android Listview中设置行背景时出现问题

在Android Listview中设置行背景时出现问题,android,listview,Android,Listview,我有一个应用程序,我希望一次一行有一种特定的颜色。这似乎在95%的情况下都能正常工作,但有时它会允许多行使用此颜色,而不是只有一行使用此颜色。具体来说,一行被设置为在点击时具有“特殊”颜色。在极少数情况下,尽管调用setBackgroundColor试图使最后一行保留颜色,但最后一行仍将保留该颜色 private OnItemClickListener mDirectoryListener = new OnItemClickListener(){ public void onItemCl

我有一个应用程序,我希望一次一行有一种特定的颜色。这似乎在95%的情况下都能正常工作,但有时它会允许多行使用此颜色,而不是只有一行使用此颜色。具体来说,一行被设置为在点击时具有“特殊”颜色。在极少数情况下,尽管调用setBackgroundColor试图使最后一行保留颜色,但最后一行仍将保留该颜色

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)时设置了
播放
属性。您应该将上一电台的
播放设置为false。我认为您缺少了一些小东西。我已经删除了对Radio类中视图的所有引用,现在调用invalidateRows()来强制重新绘制ListView。这会产生正确的行为。如果我尝试使用我跟踪的ID从listview获取视图,我应该调用什么函数?调用getView()似乎不正确。若要获取现有视图,请使用ListView.getChildAt()