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

时间:2015-04-21 06:39:06

标签: android android-listview baseadapter

我创建的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));
 }
}

以下是我用于个人联系的模型类:

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;
    }
}

4 个答案:

答案 0 :(得分:2)

我想问题出在这里:

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

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

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

答案 1 :(得分:0)

试试这个

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

示例项目也可供您查看。请仔细阅读

答案 2 :(得分:0)

这就是我的所作所为:

  • 自定义适配器:

    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 in Spanish)制作的,每个地方都有一些属性,包括照片和名字等等。如您所见,当我创建适配器时,我向他发送了一系列的地方。方法getView()返回为数组的每个元素充气的布局。您必须创建自定义联系人类或类似的东西,包括联系人和照片的名称,创建联系人数组,并在创建自定义适配器时发送该数组。

- 包含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:使用此功能的Acitivty示例:

-XML用于活动(包含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>
  • 活动代码

    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;
        }
    
    
    }
    

答案 3 :(得分:0)

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

   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);

尝试使用此自定义适配器并显示名称为..

的图像