[英]How to set the text of a TextView asynchronously?
我必須使用需要時間收集的文本信息填充ListView
。 我的方法是使用AsyncTask來執行后台作業,但是當結果到達時將文本設置為TextView會減慢列表:每次調用getView()
時列表都會滯后。
這是我的AsyncTask
類
private class BreadcrumbTask extends AsyncTask<FFile, Void, String>{
private WeakReference<TextView> mTextView;
public BreadcrumbTask(TextView textView){
mTextView = new WeakReference<TextView>(textView);
}
@Override
protected String doInBackground(FFile... params) {
// text processing
}
@Override
protected void onPostExecute(String result) {
if (mTextView != null){
TextView tv = mTextView.get();
if (tv != null)
//this line blocks the UI. if I comment it the lag is gone
tv.setText(result);
}
// mTextView.setText(result); }
我在getView()中創建了一個新任務,然后執行它。 問題顯然來自tv.setText(result)
中的onPostExecute()
。 當我評論列表很好地流動。 那么如何在不降低UI的情況下更新TextView
呢?
使用ViewHolder模式。
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
在視圖持有者中保持視圖對象
在滾動ListView期間,您的代碼可能經常調用findViewById(),這會降低性能。 即使適配器返回一個膨脹的視圖以進行回收,您仍然需要查找元素並更新它們。 重復使用findViewById()的方法是使用“視圖持有者”設計模式。
ViewHolder對象將每個組件視圖存儲在Layout的標記字段中,因此您可以立即訪問它們而無需重復查找它們。 首先,您需要創建一個類來保存您的確切視圖集。 例如:
static class ViewHolder {
TextView text;
TextView timestamp;
ImageView icon;
ProgressBar progress;
int position;
}
然后填充ViewHolder並將其存儲在布局中。
ViewHolder holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);
holder.text = (TextView) convertView.findViewById(R.id.listitem_text);
holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);
holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);
convertView.setTag(holder);
其他一些例子:
http://xjaphx.wordpress.com/2011/06/16/viewholder-pattern-caching-view-efficiently http://www.jmanzano.es/blog/?p=166
您無法從其他線程更新UI。 但您可以使用Handler動態更新UI。 在類中定義一個處理程序並按如下方式使用它:
宣言:
String result = "";
Handler regularHandler = new Handler(new Handler.Callback() {
public boolean handleMessage(Message msg) {
// Update UI
if(msg.what==3){
if (mTextView != null){
TextView tv = mTextView.get();
if (tv != null){
//this line blocks the UI. if I comment it the lag is gone
tv.setText(result);
}
}
}
return true;
}
});
您在onPostExecute中的代碼
@Override
protected void onPostExecute(String result) {
//store the value in class variable result
this.result = result;
handler.sendEmptyMessage(3);
}
@Override
protected void onPostExecute(String result) {
if (mTextView != null){
TextView tv = mTextView.get();
if (tv != null)
//this line blocks the UI. if I comment it the lag is gone
tv.setText(result);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.