11

ArrayAdapter を使用して項目をカスタム ListView に追加し、結果を Android アプリに表示しています。私が抱えている問題は、ArrayAdapter がビューを表示する前にすべての項目が入るまで待機しているように見えることです。つまり、項目を ArrayAdapter に追加し、notifyDataSetChanged を呼び出すと、追加された項目を表示するために ListView が更新されません。すべてのアイテムが追加され、アイテムを表示する前に GetView が呼び出されるまで待機します。

私がやりたいのは、ListViewに追加した直後にアイテムを表示することです。これは可能ですか?

関連するコードは次のとおりだと思います。

r_adapter = new ReminderAdapater(Activity_ContentSearch.this, R.layout.search_listitem, myList);
listView.setAdapter(r_adapter);
...
r_adapter.notifyDataSetChanged();
r_adapter.clear();
for(int i = 0; i < myList.size(); i++)
{
    r_adapter.add(myList.get(i));
    r_adapter.notifyDataSetChanged();
}

ご覧のとおり、add メソッドの後で notifyDataSetChanged を呼び出していますが、実際にはビューは更新されません。上記のループが終了した後、ビューは最終的に更新されます (私が知っていることに基づいて、これは、コードのこのセクションが完了するまで GetView が呼び出されないためです)。

カスタム ArrayAdapter の add メソッドをオーバーライドしようとしましたが、そのメソッドのビューにアクセスできないため、うまくいきませんでした。

どんな助けでも大歓迎です:)

バラ

4

1 に答える 1

23

Android の UI はシングルスレッドです。アダプターにエントリを追加するたびに、メイン アプリケーション スレッドから Android に制御を戻すわけではありません。したがって、Android は、ユーザーが制御を戻すまでエントリを表示する機会がありません。また、アダプタ全体にデータを入力するまで、エントリを表示することはありません。

以下は、バックグラウンド スレッドを介してプログレッシブAsyncTaskに を埋めるための の使用を示す例です。ArrayAdapter

/***
  Copyright (c) 2008-2012 CommonsWare, LLC
  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain   a copy
  of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
  by applicable law or agreed to in writing, software distributed under the
  License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS
  OF ANY KIND, either express or implied. See the License for the specific
  language governing permissions and limitations under the License.

  From _The Busy Coder's Guide to Android Development_
    http://commonsware.com/Android
*/

package com.commonsware.android.async;

import android.app.ListActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.util.ArrayList;

public class AsyncDemo extends ListActivity {
  private static final String[] items={"lorem", "ipsum", "dolor",
                                      "sit", "amet", "consectetuer",
                                      "adipiscing", "elit", "morbi",
                                      "vel", "ligula", "vitae",
                                      "arcu", "aliquet", "mollis",
                                      "etiam", "vel", "erat",
                                      "placerat", "ante",
                                      "porttitor", "sodales",
                                      "pellentesque", "augue",
                                      "purus"};
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    setListAdapter(new ArrayAdapter<String>(this,
                        android.R.layout.simple_list_item_1,
                        new ArrayList<String>()));

    new AddStringTask().execute();
  }

  class AddStringTask extends AsyncTask<Void, String, Void> {
    @Override
    protected Void doInBackground(Void... unused) {
      for (String item : items) {
        publishProgress(item);
        SystemClock.sleep(200);
      }

      return(null);
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void onProgressUpdate(String... item) {
      ((ArrayAdapter<String>)getListAdapter()).add(item[0]);
    }

    @Override
    protected void onPostExecute(Void unused) {
      Toast
        .makeText(AsyncDemo.this, "Done!", Toast.LENGTH_SHORT)
        .show();
    }
  }
}
于 2010-01-25T10:54:03.417 に答える