所以我有了这段代码(为解决方案而更新)。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
...
final Direction d = directions.get(position);
if (d != null) {
TextView direction = (TextView) row.getTag(R.id.directionTextView);
TextView departure1 = (TextView) row.getTag(R.id.departure1);
TextView departure2 = (TextView) row.getTag(R.id.departure2);
TextView departure3 = (TextView) row.getTag(R.id.departure3);
direction.setText(d.getName());
if (d.getTimeStamps().size() == 0) {
departure1.setText(R.string.nodepartures);
departure1.setTextColor(R.color.grey);
} else {
for (int i = 0; i < d.getTimeStamps().size(); i++) {
switch (i) {
case 0:
departure1.setText(d.getTimeStamps().get(i));
break;
case 1:
departure2.setText(d.getTimeStamps().get(i));
break;
case 2:
departure3.setText(d.getTimeStamps().get(i));
break;
default:
break;
}
}
}
}
return row;
}
}
我遇到的问题是,当一个TextViews不应该变成灰色时会变灰。我试着通过将文本再次设置为黑色来修复它,但是这会使每一个都变成灰色。直到我尝试:
setTextColor(context.getResources().getColor(R.color.black));
而不仅仅是
setTextColor(R.color.black);
当设置文本灰色时,不知道为什么后者有效,但确实如此。我想我只是有点迟钝。 :)
答案 0 :(得分:3)
您认为发生的事情根本不可能发生(*
,**
)。你需要做的是向自己证明它没有发生。
我是通过在代码中添加一些跟踪图来实现的。将一个放在if
语句之前,一个放在“then”和“else”子句的开头,一个放在if语句之后。然后运行它。我希望这会显示if
语句实际上正在运行两次,第一次运行“then”子句,第二次运行“else”子句。
(*理论上,如果模拟器中存在严重错误,可能会发生这种情况。但是如果你有无可辩驳的证据,你应该只考虑这种情况。)
(**另一种可能性是,上面的示例代码与您正在测试的实际代码之间可能存在显着差异。它会发生......)
答案 1 :(得分:2)
AsLanFromNarnia走在正确的轨道上。 ListView回收其子视图。您永远不能假设convertView
处于任何类型的默认状态。每次调用getView
时设置每个相关字段。在您的情况下,这意味着在设置文本时设置文本颜色。
还有另一种处理此类案例的方法,您希望拥有异构列表:使用视图类型。您的适配器可以返回getViewTypeCount
所拥有的类型数,然后报告getItemViewType
中每个项目的类型。如果您这样做,您将始终将convertView
传递到正确类型的getView
方法,从而减少每次更改静态布局的需要。
答案 2 :(得分:0)
答案 3 :(得分:0)
我同意Aircule!这段代码非常糟糕!怎么样?
if(d.getTimeStamps().isEmpty())
{
departure1.setText(R.string.nodepartures);
departure1.setTextColor(R.color.grey);
}
else
{
departure1.setText(d.getTimeStamps().get(0));
departure2.setText(d.getTimeStamps().get(1));
departure3.setText(d.getTimeStamps().get(2));
}
它应该做同样的事情,它不那么复杂。另外,假设您运行此代码一次并且列表为空,因此您将departure1的颜色设置为灰色并再次运行它。这次你得到数据并填写项目,但你永远不会改变departure1的颜色,所以它会保持灰色。同样,如果您反过来采用该方案,则在列表为空时不会清空TextViews
。另一个提示,如果只有三个项目(或任何小的固定数量的项目),那么你可能最好只使用普通的布局而不是列表。这样您就不必通过制作自定义适配器,只需按名称调用项目即可。
答案 4 :(得分:0)
根据您描述的内容,我们只能提供最佳提示。
作为代码改进,我会执行以下操作来重构switch
(假设控制类型为Text
,这可能是错误的,但很容易修复):
if (d.getTimeStamps().isEmpty()) {
departure1.setText(R.string.nodepartures);
departure1.setTextColor(R.color.grey);
} else {
Text[] fields = new Text[] { departure1, departure2, departure3 };
for (int i = 0; i < fields.length && i < d.getTimeStamps().size(); i++) {
fields[i].setText(d.getTimeStamps().get(i));
fields[i].setTextColor(R.color.black);
}
}
<强>更新强>
如果您没有为出发值设置颜色,我认为您假设在此代码运行时新创建了这些行。如果这个假设不正确,你的情况可能是以前持有“无离开”线的一条线现在被重新用于出发线,因此继承了灰色。
答案 5 :(得分:0)
您是否在LayoutInflator加载的布局XML文件中设置了默认颜色或样式?
答案 6 :(得分:0)
我认为它变灰了,因为在你的程序中的某个时刻,该方法被调用0个时间戳。
它只需要发生一次设置departure1.textColor属性,然后它会一直存在直到更改回来。
你提到过你曾尝试在else语句中将其设置为黑色,但它将所有内容都变为灰色。这根本没有意义。尝试添加命令以在每个case语句处将文本转换为黑色,所以:
case 0:
departure1.setTextColor(R.color.black);
departure1.setText(d.getTimeStamps().get(i));
break;
case 1:
departure2.setTextColor(R.color.black);
departure2.setText(d.getTimeStamps().get(i));
break;
case 2:
departure3.setTextColor(R.color.black);
departure3.setText(d.getTimeStamps().get(i));
break;