3

私はかなり不可解な問題を抱えています。ListView に AsyncTask を設定しようとすると、その ListView のアダプタで getView() が呼び出されることはありません。これは、アクティビティが開始されたときのこの ListView のデータの初期設定であることに注意してください。ListView は HTTP から入力されるため、AsyncTask が必要です。

次の簡単なレイアウトがあります。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
<ListView  
    android:id="@+id/transactionListView"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:divider="#CCCCCC"
    android:dividerHeight="1px"
    />
</LinearLayout>

そして基本的な onCreate():

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mainListView = (ListView)findViewById(R.id.transactionListView);
    this.populateListView();
}

あなたが電話を見ることができるのは:

private void populateListView()
{
    populateListViewTask task = new populateListViewTask();
    task.execute();
}

そして最後に、AsyncTask onPostExecute():

protected void onPostExecute(Void result)
{
    lvAdapter = new CustomArrayAdapter(MainActivity.this, R.layout.listitem, data);
    mainListView.setAdapter(lvAdapter);
}

もちろん、実際の実装はそれよりも少し複雑ですが、上記の構成で getView() が呼び出されないことを除いて、他のエラーの原因を排除しました。onPostExecute() に lvAdapter.getCount() を追加すると、30 になります (実際のコードの HTTP/XML 解析部分が適切に機能しているため、これは予想どおりです)。また、にやにや笑いのために、notifyDataSetChanged() を追加しようとしましたが、CustomArrayAdapter は、名前が示すように、ArrayAdapter を拡張したものです。ビューでinvalidate()も試しましたが、効果はありませんでした。

ただし、AsyncTask を呼び出す前に、onCreate() を次のように 1 つのダミー リスト項目に変更すると、次のようになります。

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mainListView = (ListView)findViewById(R.id.transactionListView);

    //Add dummy list item
    TestDataStructure[] data = new TestDataStructure[1];|
    data[0] = new TestDataStructure();
    data[0].item = "Dummy List Item";
    lvAdapter = new CustomArrayAdapter(MainActivity.this, R.layout.listitem, data);
    mainListView.setAdapter(lvAdapter);

    this.populateListView();
}

getView() は onPostExecute() 呼び出しの後に適切に呼び出され、ListView には AsyncTask からの新しい項目が適切に取り込まれます。私の推測では、元のケースでは、Android はアクティビティの作成サイクル中にレイアウト内の項目の構造と可視性を決定し、transactionListView が空であるため非表示であると判断し、新しいアダプターが作成されたときに getView() を呼び出さないようにします。が設定されています。

ダミーのリスト項目を追加せずにこれを修正する方法についてのアイデアはありますか (もちろん、AsyncTask が終了するまで表示されます)。私のアクティビティは、ListActivity ではなく Activity を拡張します。

ありがとう!

4

2 に答える 2

1

データが の場合、 thisで割り当て、これでアダプターを割り当てるArrayList<String>ことができます。これにより、asynctask が終了するまで ListView が空のままになります。データに値を割り当てて、データが this で変更されたことをアダプターに通知できます。onCreate()data = new ArrayList<String>();adapter.notifyDataSetChanged()

于 2012-04-19T01:41:08.293 に答える
0

アダプターにデータが入力された後、アダプターで notifyDataSetChanged() を呼び出す必要があるようです。これは UI スレッドから呼び出す必要があるため、postExecute() メソッドから直接呼び出されるコードに入れます。

これが役立つ場合は、これを回答としてマークしてください。

于 2012-04-19T01:30:27.823 に答える