簡體   English   中英

如何異步設置TextView的文本?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM