3

ListView収集に時間がかかるテキスト情報を入力する必要があります。getView()私のアプローチは、AsyncTaskを使用してバックグラウンドジョブを実行することですが、結果が到着したときにテキストをTextViewに設定すると、リストの速度が低下します。リストは、呼び出されるたびに遅れます。

これは私の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()ます。コメントすると、リストはうまく流れます。TextViewでは、UIを遅くせずにを更新するにはどうすればよいですか?

4

3 に答える 3

1

ViewHolderパターンを使用します。

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

ビューホルダーにビューオブジェクトを保持する

ListViewのスクロール中にコードがfindViewById()を頻繁に呼び出す可能性があり、パフォーマンスが低下する可能性があります。アダプタがリサイクルのために膨張したビューを返した場合でも、要素を検索して更新する必要があります。findViewById()を繰り返し使用する方法は、「ビューホルダー」デザインパターンを使用することです。

ViewHolderオブジェクトは、各コンポーネントビューをレイアウトのタグフィールド内に格納するため、繰り返し検索しなくてもすぐにアクセスできます。まず、ビューの正確なセットを保持するクラスを作成する必要があります。例えば:

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

于 2012-07-12T17:17:05.470 に答える
0

別のスレッドからUIを更新することはできません。ただし、ハンドラーを使用して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);
        }
于 2012-07-12T17:16:11.567 に答える
0
  @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); 

}
于 2012-07-12T17:25:21.533 に答える