我已经创建了一个自定义ListView适配器/项目。该项包含CheckedTextView和TextView。
在适配器的getView()方法中,创建自定义项并在返回之前调用其setTask(Task)方法。
setTask(Task)方法从作为参数传入的Task对象中获取2个字符串和一个布尔值。 (我确实认识到它的地址实际上是通过的。)
其中一个字符串被分配给自定义项的TextView的文本属性,如果该字符串包含文本。否则,TextView的visible属性设置为“gone。”
为了做出这个决定,我检查字符串的长度是否小于或等于0 ......它会产生意外行为 - 它总是评估为真。
如果我改变它以检查String是否等于“”,它总是返回false。
这让我相信我正在检查的String是null。为什么会这样?
protected void onFinishInflate() {
super.onFinishInflate();
checkbox = (CheckedTextView)findViewById(android.R.id.text1);
description = (TextView)findViewById(R.id.description);
}
public void setTask(Task t) {
task = t;
checkbox.setText(t.getName());
checkbox.setChecked(t.isComplete());
if (t.getDescription().length() <= 0)
description.setVisibility(GONE);
else
description.setText(t.getDescription());
}
这是适配器中的getView()方法:
public View getView(int position, View convertView, ViewGroup parent) {
TaskListItem tli;
if (convertView == null)
tli = (TaskListItem)View.inflate(context, R.layout.task_list_item, null);
else
tli = (TaskListItem)convertView;
tli.setTask(currentTasks.get(position));
return tli;
}
答案 0 :(得分:6)
myString == ""
检查字符串对象的引用而不是内容。你应该使用:
"".equals(myString)
检查字符串的内容,而不是引用。你可以使用:
myString.equals("")
但如果myString为null,则有可能出现NullPointerException。
答案 1 :(得分:2)
在Java中,您不能使用==将String的内容与另一个String进行比较。 ==运算符始终比较变量的引用或内存地址。在其他语言中,可以==来比较对象的内容。在Java中它不能。使用.equals()或.equalsIgnoreCase()。
答案 2 :(得分:0)
您正在使用==来比较字符串,这对于对象来说总是一个坏主意。空字符串“”指向与t.getDescription()不同的String对象,但值可能相同。使用字符串有时候==会起作用,因为String类维护着一个字符串池,它将用于字符串文字和常量。然而,演示String如何工作比单词更好。
public class StringTest
{
public static void main(String[] args)
{
String s0=""; // literal
System.out.println("Length of s0 = " + s0.length());
System.out.println("Does s0 point to same object as empty string? "
+ (s0=="")); // since both are literals the same object is used for both
System.out.println("Does s0 equal an empty string? "
+ s0.equals("")); // comparing values
System.out.println("Is s0 empty? " + s0.isEmpty());
System.out.println("");
StringBuilder sb = new StringBuilder("");
String s1 = sb.toString(); // don't use a literal for s1
System.out.println("Length of s1 = " + s1.length());
System.out.println("Does s1 point to same object as empty string? "
+ (s1=="")); // s1 is a different object
System.out.println("Does s1 equal an empty string? " + s1.equals(""));
System.out.println("Is s1 empty? " + s1.isEmpty());
System.out.println("");
// Do this like s1 but with a twist
sb = new StringBuilder("");
String s2 = sb.toString(); // again not a literal
System.out.println("Does s2 point to same object as empty string? "
+ (s2==""));
System.out.println("Length of s2 = " + s0.length());
s2 = s2.intern(); // returns the object from the pool that equals() s2
System.out.println("Now does s2 point to same object as empty string? "
+ (s2=="")); // s2 now has the reference to the empty string in the pool
System.out.println("Does s2 equal an empty string? " + s2.equals(""));
System.out.println("Is s2 empty? " + s2.isEmpty());
}
}
我希望这会有所帮助。
答案 3 :(得分:0)
此外,你应该在使用.length()之前检查t.getDescription()。
if(t.getDescription()!=null){
(t.getDescription().length()>0)?description.setText(t.getDescription()):description.setVisibility(GONE);}
else { description.setVisibility(GONE);}
为避免使用String,请确保t-> description完全以null开头而不是空字符串。这可以在Class构造函数中完成。
答案 4 :(得分:0)
事实证明,除了直接比较String对象之外,我还有另一个严重的错误。 (如果我错了,请纠正我。)
由于ListView中的视图有时会被回收,因此“tli”引用有时会引用一个视图,其可见性属性已设置为“已消失”。即使字符串不为空,该属性也永远不会变回“可见”。我只需要在两种情况下明确设置该属性。这是固定代码:
public void setTask(Task t) {
task = t;
checkbox.setText(task.getName());
checkbox.setChecked(task.isComplete());
if (task.getDescription().equals(""))
description.setVisibility(GONE);
else
description.setVisibility(VISIBLE);
description.setText(task.getDescription());
}
无论我是否从task.getDescription()检查字符串的内容或长度,它现在都起作用。
答案 5 :(得分:-1)
==
运算符检查双方是否引用同一对象。具有相同内容的两个字符串不会(通常)引用同一个对象,请参见下文。
String s = "";
String t = "";
if (s == t){
//false! s and t refer to different objects
}
if (s.equals(t) && t.equals(s)){ //these two are equivalent
//true!
}
s = t;
if (s == t){
//now they refer to the same object, so true!
}