9

Fragments を使用して連絡先リスト アプリを作成しています。1 つのフラグは連絡先リスト内の名前のリストであり、もう 1 つのフラグは残りの詳細です。

名前のリストを表示するクラスは次のとおりです。

public class MyListFragment extends ListFragment {

private ContactStorage contactStorage = new ContactStorage();

public final static String TAG = "FRAGMENTS";
private MainActivity parent;
ArrayAdapter<String> adapter;

ArrayList<String> entries = new ArrayList<String>();

String array[];

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.list_layout, null);
    parent = (MainActivity) getActivity();
    entries = contactStorage.getContactListNames();

    adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(), 
            android.R.layout.simple_list_item_1, entries);

    setListAdapter(adapter);
    Log.d(TAG, "Adapter created");
    array = contactStorage.getContactDetails();
    return v;

}

@Override
public void onResume() {

    super.onResume();
    entries = contactStorage.getContactListNames();
    adapter.notifyDataSetChanged();
    Log.d(TAG, "List Frag Resumed");

}
}

私が抱えている問題は、再開時に ArrayAdapter が更新されないことです。

画面が回転すると、onCreateView() が再度実行されるので問題ありませんが、onResume を更新する必要があります。このサイトの読み込みを調べたところ、機能しない「notifyDataSetChanged() を使用」しか見つかりませんでした。

4

2 に答える 2

29

あなたが抱えている問題は、エントリ参照を上書きしていて、アダプタで変更されていないことです。これを修正する方法は次のとおりです

@Override
public void onResume() {

    super.onResume();
    entries.clear();
    entries.addAll(contactStorage.getContactListNames());
    adapter.notifyDataSetChanged();
    Log.d(TAG, "List Frag Resumed");

}

これはよくある間違いです。最初に (メモリ内に) リストを作成し、entriesフィールドがそれを指しているadapterときに、作成時にそのメモリの場所を参照するように に指示しているonResumeのに、新しいリストをメモリ (連絡先リストの名前を再度取得するとき) で、エントリにメモリ内の新しいリストを指すように指示する場合、元のリストのエントリを新しいリストのエントリに置き換える必要がありますadapter。同じリストを参照してください。

于 2013-04-25T16:21:14.117 に答える
5

notifyDataSetChanged() won't work for you. Reasons why

Your adapter loses reference to your list. When you first initialize the Adapter it takes a reference of your arrayList and pass to its superclass. But if you reinitialize your existing arrayList it losts the reference hence the communication channel with Adapter :(.

Always creating and adding a new list to the Adapter. Do like this:

  1. Initialize the arrayList while declaring globally.
  2. Add List to the adapter directly with out checking null and empty condition. Set the adapter to the list directly(don't check for any condition). Adapter gives you the guarantee that wherever you are changes the data of arrayList it will take care, but never loose the reference.
  3. 毎回arrayListにデータを追加します(データが完全に新しい場合は、実際にリストにデータを追加する前にadapter.clear()およびarrayList.clear()を呼び出すことができます)が、アダプターを設定しないでください。つまり、新しいデータがadapter.notifyDataSetChanged() だけでなく、arrayList に入力されます。

ドキュメンテーションへの信頼を保つ

于 2013-12-09T19:22:08.560 に答える