TextView.settextColor会影响多个项目

时间:2014-01-14 11:12:28

标签: android baseadapter

我的Android UI问题似乎无法解决。 我的主要活动(ListActivity)显示项目列表。当用户单击一个时,它会通过AsyncTask更新基础数据(从Web服务查询)。请求成功终止后,我呼叫notifyDataSetChanged()以显示新信息。 我的理解是,我的自定义getView中的BaseAdapter方法将被调用来执行渲染:

private List<InstalledApp> data;

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    if (convertView == null) {
        convertView = LayoutInflater.from(ctx).inflate(R.layout.list_item, parent, false);
    }
    InstalledApp app = data.get(position);
    String latest_version = app.getLatestVersion();
    TextView version = (TextView) convertView.findViewById(R.id.version);

    if (latest_version != null)
    {
        if (app.getVersion().equals(latest_version))
        {
            version.setText(app.getVersion());
            version.setTextColor(Color.GREEN);
        }
        else
        {
            version.setText(app.getVersion() + " (Current: " + latest_version + ")");
            version.setTextColor(Color.RED);
        }
    }
    else {
        version.setText(app.getVersion());
    }

    return convertView;
}

问题是,当项目被更新并且被调用时,两个项目的颜色会发生变化。但文字内容仍然正确。第二个通常不会立即显示,我必须向下滚动列表才能看到它。 你知道造成这种情况的原因吗?

3 个答案:

答案 0 :(得分:1)

发生此问题,因为convertView正在被回收。要解决您的问题,请确保在IF语句中为convertView设置一些属性时,需要在ELSE语句中重置这些属性,以确保在重用视图时,特定条件不再适用时,您的属性是回到默认值。

在您的特定情况下:

  • 对于列表中的第一项,这些条件可能为真:(latest_version!= null)AND(app.getVersion()。equals(latest_version)),因此将textColor设置为GREEN

    < / LI>
  • 然后向下滚动,此视图将重新用于另一个列表项,因为不再可见(这是listView因性能原因而设计的方式)。现在,对于这个新的列表项可能有不同的条件,特别是:(latest_version == null) - &gt;这会导致此行被称为version.setText(app.getVersion());,因此您的新列表项具有正确的文本,但您没有为此方案设置textColor,因此textColor保持不变(在重复使用视图之前设置)。

所以要解决您的问题,请参阅以下代码:

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    if (convertView == null) {
        convertView = LayoutInflater.from(ctx).inflate(R.layout.list_item, parent, false);
    }
    InstalledApp app = data.get(position);
    String latest_version = app.getLatestVersion();
    TextView version = (TextView) convertView.findViewById(R.id.version);

    if (latest_version != null)
    {
        if (app.getVersion().equals(latest_version))
        {
            version.setText(app.getVersion());
            version.setTextColor(Color.GREEN);
        }
        else
        {
            version.setText(app.getVersion() + " (Current: " + latest_version + ")");
            version.setTextColor(Color.RED);
        }
    }
    else {
        version.setText(app.getVersion());
        version.setTextColor(Color.GREEN); // YOU NEED TO ALSO SET CORRECT COLOR HERE
    }

    return convertView;
}

答案 1 :(得分:1)

How ListView's recycling mechanism works

您正面临这个问题,因为listview会回收视图。

您可以尝试以下方法来克服它

public class InstalledApp
{
   ...// rest of the code
   ...// setter an getter for version
   int color;
   public void setColor(int color)
   {
       this. color = color;
   }  
   public int getColor()
   {
        return color;
   }
}

填充List<InstalledApp> data;时。此列表可以循环填充。以下只是一个例子。

 InstalledApp app = new Installedapp();
 if(version.equals(latest_version); // you condition to check latest version
 { 
       app.setColor(Color.GREEN);
 } 
 else
 {
       app.setColor(Color.RED);
 } 
 ...// setter for version here
 data.add(app); 

将填充的列表传递给适配器类

的构造函数

然后在getView

InstalledApp app = data.get(position);
version.setText(app.getVersion() + " (Current: " + latest_version + ")");
version.setTextColor(app.getColor());

答案 2 :(得分:0)

试试这个

private List<InstalledApp> data;
 int[] colors=new int[data.size()];
 @Override
 public View getView(int position, View convertView, ViewGroup parent)
  {
    if (convertView == null) {
    convertView = LayoutInflater.from(ctx).inflate(R.layout.list_item, parent, false);
  }
 InstalledApp app = data.get(position);
 String latest_version = app.getLatestVersion();
 TextView version = (TextView) convertView.findViewById(R.id.version);

 if (latest_version != null)
 {
    if (app.getVersion().equals(latest_version))
    {
        version.setText(app.getVersion());
        colors[position]=Color.GREEN;
        version.setTextColor(colors[position]);
    }
    else
    {
        version.setText(app.getVersion() + " (Current: " + latest_version + ")");
        colors[position]=Color.RED;
        version.setTextColor(colors[position]);
    }
}
else {
       version.setText(app.getVersion());
}

return convertView;

}