我创建了一个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;
}
}
问题就在这里:
image.setImageURI(Uri.parse(temp.image));
如果您的联系人没有图像,则您正在尝试解析null
。
我不是 100% 确定,但由于您没有提供任何堆栈跟踪,我想这就是问题所在。
试试这个
https://developer.android.com/training/contacts-provider/display-contact-badge.html
示例项目也供您检查。 请通过这个
使用此代码并创建自定义适配器。
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);
尝试此自定义适配器并显示带有名称的图像。
好吧,这就是我所做的:
-
定制适配器:
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>
好吧,这个自定义适配器是为地方(西班牙语中的Lugar)制作的,每个地方都有一些属性,包括照片和名称,所以。如您所见,当我创建适配器时,我会向他发送位置数组。该方法getView()
返回数组的每个元素膨胀的布局。您必须创建自定义联系人类或类似的东西,包括联系人姓名和照片,创建联系人数组,并在创建自定义适配器时发送该数组。
-在包含列表视图的活动中:
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(包含列表视图)
<?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; } }