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,而是存储对它的引用
  • 不要每次都设置新的适配器,而是更改底层数据并调用
  • 总是在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

像这样放在 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 回答
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 回答