0

こんにちは、SQLite データベースから連絡先を追加する ListFragment を使用しています。次に、ListFragment を更新したいのですが、うまくいきません。

これは、ListFragment に連絡先を追加するために ActionBar の項目をクリックした後に AlertDialog を表示する、私の Fragment 内のコードです。

//Handle OnClick events on ActionBar items
@Override
public boolean onOptionsItemSelected(MenuItem item) {
   // handle item selection
   switch (item.getItemId()) {
      case R.id.menu_add:
         Toast.makeText(getActivity(), "Click", Toast.LENGTH_SHORT).show();

         LayoutInflater factory = LayoutInflater.from(getActivity());

         //textEntryView is an Layout XML file containing text field to display in alert dialog
         textEntryView = factory.inflate(R.layout.dialog_add_room, null);       

         //get the control from the layout      
         enter_room = (EditText) textEntryView.findViewById(R.id.enter_room);

         //create Dialog
         final AlertDialog.Builder alert1 = new AlertDialog.Builder(getActivity());
         //configure dialog
         alert1.setTitle("Raum hinzufügen:").setView(textEntryView)
         .setPositiveButton("Hinzufügen",
                new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,
                    int whichButton) {
                String roomname = enter_room.getText().toString();

                Log.d("Insert: ", "Inserting ..");
                dbHandler.addContact(new Contact(roomname, "0"));

                adapter.notifyDataSetChanged();
            }
         }).setNegativeButton("Abbrechen",
                new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,
                    int whichButton) {
                //cancel dialog
            }
         });
         alert1.show();          
         return true;
      default:
         return super.onOptionsItemSelected(item);
   }
}

OnCreate() メソッド内で定義されたアダプター:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //display ActionBar items
    setHasOptionsMenu(true);

    //database
    dbHandler = new DatabaseHandler(getActivity());

    //get all contacts
    contacts = dbHandler.getAllContacts();

    adapter = new ArrayAdapter<Contact>(getActivity(),
            android.R.layout.simple_list_item_activated_1,
            android.R.id.text1, contacts);

    adapter.setNotifyOnChange(true);

    //show all contacts in the ListFragment
    setListAdapter(adapter);
}

何が問題ですか?

4

1 に答える 1

1

コードonCreateDatabaseHandlerクラスを使用して、データベースからすべての連絡先を配列またはList何らかの種類にロードします。後で、クリック ハンドラーによって別の連絡先がデータベースに追加されますが、配列は変更されません。データベースではなく、指定したArrayAdapter配列についてのみ知っているため、adapter.notifyDataSetChanged();効果はありません。

2 つの方法があります。

  1. ArrayAdapterとセットアップ コードを に置き換えることができますLoader。これを行う最も簡単な方法は、 経由でデータベースにアクセスすることです。これはContentProvider、 を使用できることを意味し、変更がや別のCursorLoaderからのものであっても、データベースが変更されたときにアダプタの更新を処理します。のオーバーヘッドが必要ない場合でも を使用できますが、実行される作業は少なくなります。どちらの方法でも、バックグラウンド スレッドで読み込みを実行できるという利点があるため、多くの連絡先がある場合に「アプリが応答していません」というメッセージが表示されることはありません。詳細については、Android Developers のローダー ガイドを参照してください。ServiceActivityLoaderContentProviderLoader

  2. この問題のより迅速で短期間の修正は、データベースの更新と同時にアダプターに与えた配列を編集することです。行を置き換えることでこれを行うことができます

    dbHandler.addContact(new Contact(roomname, "0"));
    

    Contact newContact = new Contact(roomname, "0");
    dbHandler.addContact(newContact);
    contacts.add(newContact);
    

    この方法では、連絡先を変更または削除するときに同様のことを行う必要があり、データベースが外部から変更された場合は更新されませんListFragment。しばらくの間、これらの余分な呼び出しを追加し続けることができることに気付くでしょうが、最終的には、それを機能させるために別の方法で行わなければならない操作に直面することになります。

于 2013-03-23T19:47:24.950 に答える