我必须使用扩展基本适配器的自定义适配器在列表视图中显示所有联系人的联系人信息(姓名、号码、图像)

I have to Display Contacts info (Name, Number, Image) of all contacts in a List View, using custom adapter which extends base adapter

我创建了一个 ListView,它应该显示联系人-(姓名、号码、图片)。

我检索到姓名和号码,但无法显示图像。

我用的是自定义适配器这里是适配器代码

public class PranzAdapter extends BaseAdapter {

ArrayList<SingleRow> list;
Context c;

PranzAdapter(Context context, ArrayList<SingleRow> listItem){
    c = context;
    list= listItem;
}

@Override
public int getCount() {
    return list.size();
}

@Override
public Object getItem(int position) {
    return list.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View row =  inflater.inflate(R.layout.single_row,null,false);

    TextView name   = (TextView) row.findViewById(R.id.textView1);
    TextView number = (TextView) row.findViewById(R.id.textView2);
    ImageView image = (ImageView) row.findViewById(R.id.imageView);

    SingleRow singleRow = list.get(position);

    name.setText(singleRow.name);
    number.setText(singleRow.number);

 //Error is this, Previously when any contact doesn't have image it pass `null`  

  if (singleRow.image!= null) {
        image.setImageURI(Uri.parse(singleRow.image));
    }
    return row;
 }
}

更新:我没有为联系人图片放置任何默认图片,因此如果任何联系人没有图片,它就会抛出 NullPointer,因此您可以放置​​默认图片或您必须使用 if 条件处理异常。

我可以显示姓名和号码,但在检索图像时出现问题。

这是获取联系信息的代码

public class MainActivity extends Activity {

ListView list;

ArrayList<SingleRow> listItem;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    list = (ListView) findViewById(R.id.listView);
    listItem = new ArrayList<SingleRow>();

    ContentResolver resolver = getContentResolver();
    Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

    String id;
    String name;
    String number;
    String image;
    if (cursor.getCount() > 0) {
        while (cursor.moveToNext()) {
            id   = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
            name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));


            if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
            {
                Cursor pCur = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null);
                while (pCur.moveToNext())
                {
                     number = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                     image = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));

                    SingleRow s = new SingleRow(name,number,image);
                    listItem.add(s);
                }
                pCur.close();

            }
        }
    }
    cursor.close();
    list.setAdapter(new PranzAdapter(this, listItem));
 }
}

这是型号class我个人联系用的:

public class SingleRow {

String name;
String number;
String image;

//Constructor for Single row
SingleRow (String name,String number,String  image){
    this.name = name;
    this.number = number;
    this.image = image;
    }
}

试试这个

https://developer.android.com/training/contacts-provider/display-contact-badge.html

示例项目也在那里供您检查。请通过这个

我就是这样做的:

  • 自定义适配器:

    package com.example.admin.lugaresfavoritos;
    
    import android.content.Context;
    import android.database.DataSetObserver;
    import android.graphics.Bitmap;
    import android.net.Uri;
    import android.provider.MediaStore;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ImageView;
    import android.widget.ListAdapter;
    import android.widget.TextView;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.Arrays;
    
    
    public class Adaptador_lista_lugares extends BaseAdapter {
    
    private ArrayList<Lugar> arrayLugares;
    private LayoutInflater inflador;
    private Context contexto;
    
    
    
    
    public Adaptador_lista_lugares(ArrayList<Lugar> arrayLugares, Context context) {
        this.arrayLugares = arrayLugares;
        this.inflador = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.contexto = context;
    }
    
    @Override
    public int getCount() {
        return arrayLugares.size();
    }
    
    @Override
    public Lugar getItem(int position) {
        return arrayLugares.get(position);
    }
    
    @Override
    public long getItemId(int position) {
        return arrayLugares.get(position).getId();
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    
        Lugar lugar = arrayLugares.get(position);
    
        if (convertView == null) {
            convertView = inflador.inflate(R.layout.elemento_lista_lugares, null);
        }
    
        TextView nombre = (TextView) convertView.findViewById(R.id.nombre_elemento_lista);
        ImageView foto = (ImageView) convertView.findViewById(R.id.foto_elemento_lista);
    
        nombre.setText(lugar.getNombre());
        foto.setImageResource(lugar.getPhoto());
    
        return convertView;
    
    }
    
    
    @Override
    public boolean isEmpty() {
        return arrayLugares.isEmpty();
    }
    
    
    
    }
    
  • XML 自定义适配器的每个元素:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:id="@+id/elemento_lista">
    
    
        <ImageView
            android:id="@+id/foto_elemento_lista"
            android:layout_width="?android:attr/listPreferredItemHeight"
            android:layout_height="?android:attr/listPreferredItemHeight"
            android:contentDescription="foto"
            android:longClickable="false"
            android:paddingTop="5dp"
            android:paddingBottom="5dp"
            android:layout_alignParentTop="true"
            android:layout_alignParentStart="true"
            android:paddingLeft="10dp" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="@string/lugarPorDefecto"
            android:id="@+id/nombre_elemento_lista"
            android:paddingLeft="15dp"
            android:layout_centerVertical="true"
            android:layout_toEndOf="@+id/foto_elemento_lista" />
    
    
    </RelativeLayout>
    

好吧,这个自定义适配器是为 Places(西班牙语中的 Lugar)制作的,每个地方都有一些属性,包括照片和名称,所以。如您所见,当我创建适配器时,我将位置数组发送给他。 getView() returns 方法为数组的每个元素扩充布局。您将必须创建自定义联系人 class 或类似的内容,包括联系人姓名和照片,创建联系人数组,并在创建自定义适配器时发送该数组。

-在activity中包含listView:

    lugares = cargarListaLugares2(); // Method to create arrayList of the elemnt you want
    mAdapter = new Adaptador_lista_lugares(lugares, getActivity()); //Create the custom adapter with that array
    mListView.setAdapter(mAdapter); //Set the custom adapter

希望对你有帮助,

此致

编辑:简化了我的代码逻辑,以便您更好地理解。

编辑 2:使用这个的活动示例:

-XML 对于 activity(包含 listView)

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.admin.lugaresfavoritos.MainActivity">

        <ListView android:id="@android:id/list" android:layout_width="match_parent"
         android:layout_height="match_parent" />



    </FrameLayout>
  • Activity代码

    package com.example.admin.lugaresfavoritos;
    
    import android.app.Activity;
    import android.app.FragmentManager;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    
    
    import java.util.ArrayList;
    import java.util.Iterator;
    
    
    public class MainActivity extends Activity {
    
    
        private ArrayList<Lugar> lugares;
        private ListView mListView;
        private ListAdapter mAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.MainActivity);  // Set the xml layout containing listView
    
            //load array of places( in your case contacts )
            lugares = cargarListaLugares();
            // create the adapter
            mAdapter = new Adaptador_lista_lugares(lugares, this); //parameters are array and context
    
            mListView = (ListView) findViewById(R.id.list); //instanciate the listView
            mListView.setAdapter(mAdapter); //set the adapter to the listView
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.menu_actividad_mapa, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
    
            if (id == R.id.action_settings) {
                return true;
            }
    
            return super.onOptionsItemSelected(item);
        }
    
    
        //method to create array from localDB(In this case places )
        public ArrayList<Lugar> cargarListaLugares(){
    
    
    
            ArrayList<Lugar> lugares2 = new ArrayList<>();
    
            Integer id;
            String nombre;
            String direccion;
            double longitud;
            double latitud;
            Integer telefono;
            String url;
            String comentario;
            double valoracion;
            String foto;
            boolean favorito;
    
            lugares2.clear();
    
            BDLugares GestorBD= new BDLugares(this,"lugares", null,1);
            SQLiteDatabase db = GestorBD.getWritableDatabase();
            Cursor c;
    
            c = db.rawQuery("SELECT * FROM lugares", null);
    
    
    
            while (c.moveToNext()) {
    
                id = c.getInt(0);
                nombre = c.getString(1);
                direccion = c.getString(2);
                longitud = c.getDouble(3);
                latitud = c.getDouble(4);
                telefono = c.getInt(5);
                url = c.getString(6);
                comentario = c.getString(7);
                valoracion = c.getDouble(8);
                foto = c.getString(9);
                favorito  =(c.getInt(10)>0);
    
                Lugar lug = new Lugar(id,nombre,direccion,longitud, latitud, telefono, url, comentario, valoracion, foto, favorito);
    
                lugares2.add(lug);
    
            }
            c.close();
            db.close();
    
            return lugares2;
        }
    
    
    }
    

使用此代码并创建自定义适配器..

   public class CustomAdapteCountry extends ArrayAdapter<String>{

    private Activity activity;
    private ArrayList data;
   public Resources res;
   private LayoutInflater inflater;
   private String val,imagename="photos";
private SpinnerModel tempSpin;

public CustomAdapteCountry(MainActivity context, int textViewResourceId,ArrayList objects,Resources resLocal) {
    super(context, textViewResourceId,objects);

     activity = context;
        data     = objects;
        res      = resLocal;     
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
     return getCustomView(position, convertView, parent);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
     return getCustomView(position, convertView, parent);
}

private View getCustomView(int position, View convertView, ViewGroup parent) {

    View row=inflater.inflate(R.layout.spinner_rows, parent, false);
    tempSpin=null;
    tempSpin=(SpinnerModel) data.get(position);

     TextView label        = (TextView)row.findViewById(R.id.company);
        ImageView companyLogo = (ImageView)row.findViewById(R.id.imageView1);   

        label.setText(tempSpin.getCompanyName());  

        if(val==null)
        {         

             String value= (tempSpin.getImage()).replaceAll("\s+","");


              int va=(res.getIdentifier("com.all.world.news.finder:drawable/"+value,null,null));

              if(va==0) {
                 companyLogo.setImageResource(res.getIdentifier("com.all.world.news.finder:drawable/"+value,null,null));
              }
              else{
                 companyLogo.setImageResource(res.getIdentifier("com.all.world.news.finder:drawable/"+value,null,null));                 
              }
        }


         return row;
       } 

}

以这种方式调用此适配器..

 private CustomAdapteCountry adapter;



  Resources res = getResources(); 
 adapter=new CustomAdapteCountry(this, android.R.layout.simple_expandable_list_item_1,country ,res);
    countryname.setAdapter(adapter);

试试这个自定义适配器并显示带有名称的图像..

我猜问题出在这里:

image.setImageURI(Uri.parse(temp.image));

如果您的联系人没有图像,则您正在尝试解析 null

我不是 100% 确定,但由于您没有提供任何堆栈跟踪,我想这就是问题所在。