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