0

私はAndroidを初めて使用し、連絡先を取得してリストビューに表示したいと考えています。asynctaskで連絡先を取得するためのコードは次のとおりです。各連絡先を取得した後にリストビューを更新する方法を教えてください。

protected Void doInBackground(Void... params) {
         ContentResolver cr = ReadContactsActivity.this.getContentResolver();
         Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
                null, null, null, null);

         if (cur.getCount() > 0) {
             while (cur.moveToNext()) {
                 String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                 String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                 if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                     Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
                                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
                                            new String[]{id}, null);
                     while (pCur.moveToNext()) {
                           String phone = pCur.getString(
                                  pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        //li.add("Name:"+name+",Number:"+phone);
                           publishProgress("Name:"+name+",Number:"+phone);
                     }
                     pCur.close();
                     }
                 }
             }
        return null;
    }


    // A callback method executed on UI thread, invoked by the publishProgress() 
    // from doInBackground() method
    @Override
    protected void onProgressUpdate(String... values) {
         list=(ListView) findViewById(R.id.lvDisplay);
        ArrayAdapter<String> adp=new ArrayAdapter<String> 
        (getBaseContext(),R.layout.list,R.id.label,li);
        list.setAdapter(adp);       
    }
4

3 に答える 3

6

リストビューとアダプタの使用方法はかなり異なります。

  • 毎回findViewByIdを使用するのではなく、代わりにそれへの参照を保存してください
  • 毎回新しいアダプタを設定するのではなく、基になるデータを変更して呼び出します
  • 常に1回限りのセットアップ(リストビューへの参照の取得、アダプターの初期化など)をOnPreExecute

    ListView list;
    List<String> names;
    ArrayAdapter<string> adapter;
    
    @Override
    protected void onPreExecute() {
        names = new ArrayList<String>();
        list = (ListView) findViewById(R.id.lvDisplay);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>     
            (getBaseContext(),
             R.layout.list,
             R.id.label,
             names);
        list.setAdapter(adp);  
    }
    
    // doInBackground() ...
    
    @Override
    protected void onProgressUpdate(String... values) {
         names.add(values[0])
         adapter.notifyDataSetChanged();
    }
    

注:この場合、実際には、Adapter、listView、および基になるデータの参照をAsyncTaskの外部に保持することをお勧めします。これらの参照は引き続き使用でき、必要に応じて外部クラスで使用することもできます(これは非常に可能性が高いです)。

于 2013-03-13T09:55:26.927 に答える
1

更新:アーメドは彼の答えを修正しました... https://stackoverflow.com/a/15381932/1659588

Ahmed Aeon Axanの回答に基づいて、ここに修正バージョンがあります

ListView list;
ArrayAdapter<string> adapter;

@Override
protected void onPreExecute() {
    list = (ListView) findViewById(R.id.lvDisplay);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>     
        (getBaseContext(),R.layout.list,R.id.label,li);
        list.setAdapter(adp);  
}

// doInBackground() ...

@Override
protected void onProgressUpdate(String... values) {
     adapter.add(values[0]);
     adapter.notifyDataSetChanged();
}

于 2013-03-13T10:05:45.317 に答える
1

このようにonPostExecute()に入れてください

@Override
   protected void onPostExecute(String... values) {
      super.onPostExecute(result);
      list=(ListView) findViewById(R.id.lvDisplay);
    ArrayAdapter<String> adp=new ArrayAdapter<String> 
    (getBaseContext(),R.layout.list,R.id.label,li);
    list.setAdapter(adp); 
   }
于 2013-03-13T09:57:47.637 に答える