2014-01-14 40 views
0

我有一個Android UI的問題,我似乎無法解決。 我的主要活動(a ListActivity)顯示項目列表。當用戶點擊一個時,它會導致基礎數據通過AsyncTask更新(從Web服務查詢)。當請求成功終止時,我呼叫notifyDataSetChanged()顯示新信息。 這是我的理解是,從我的自定義BaseAdaptergetView方法將被調用執行渲染:TextView.settextColor影響多個項目

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; 
} 

的問題是,當一個項目被更新,這個被調用,兩個項目都有自己的顏色變化。但文本內容仍然正確。第二個通常是不可見的,我必須向下滾動列表才能看到它。 你有什麼想法可能會造成這種情況?

+1

這種情況bcoz的ListView回收VIE W上。發佈'InstalledApp'類 – Raghunandan

+0

你能提供更多的細節樣本數據和發生了什麼... –

回答

1

發生此問題,因爲convertView正在回收。要解決你的問題,只要確保在IF語句中爲convertView設置了一些屬性時,你需要重置ELSE語句中的這些屬性,以確保當視圖被重用以及特定條件不再適用時,屬性是恢復默認。

你的具體情況:

  • 對名單上的第一個項目,這些條件可能爲真:(!latest_version = NULL)AND(app.getVersion()等於(latest_version)),所以你設置你的textColor爲綠色

  • 然後你向下滾動,這個視圖被重新用於另一個列表項,因爲不再可見(這是如何設計listView是出於性能的原因)。現在,對於這個新的列表項目,可能會出現不同的情況,特別是:(latest_version == null) - >這會導致此行被稱爲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; 
} 
+0

謝謝!我明白現在發生了什麼事。 – executifs

1

How ListView's recycling mechanism works

您所面臨的問題,因爲列表視圖回收的觀點。

你可以試試下面去克服它

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()); 
+0

非常感謝您的回覆和回收機制的鏈接。 – executifs

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; 

}

+0

感謝您花時間回覆。我更喜歡其他答案,因爲跟蹤所有的顏色對我來說似乎沒有必要。 – executifs

相關問題