6

Estoy tratando de usar un SimpleCursorAdapter con un para obtener una imagen de la base de datos y ponerla en mi vista de elemento ListView. Aquí está mi código:Imágenes en SimpleCursorAdapter

private void setUpViews() { 
    mNewsView = (ListView) findViewById(R.id.news_list); 

    Cursor cursor = getNews(); 
    SimpleCursorAdapter curAdapter = new SimpleCursorAdapter(
      getApplicationContext(), R.layout.cursor_item, cursor, 
      new String[] { "title", "content", "image" }, 
      new int[] { R.id.cursor_title, R.id.cursor_content, 
        R.id.news_image }); 

    ViewBinder viewBinder = new ViewBinder() { 

     public boolean setViewValue(View view, Cursor cursor, 
       int columnIndex) { 
      ImageView image = (ImageView) view; 
      byte[] byteArr = cursor.getBlob(columnIndex); 
      image.setImageBitmap(BitmapFactory.decodeByteArray(byteArr, 0, byteArr.length)); 
      return true; 
     } 
    }; 
    ImageView image = (ImageView) findViewById(R.id.news_image); 
    viewBinder.setViewValue(image, cursor, cursor.getColumnIndex("image")); 
    curAdapter.setViewBinder(viewBinder); 
    mNewsView.setAdapter(curAdapter); 
} 

estoy consiguiendo una:

android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 60 

durante la ejecución de byte[] byteArr = cursor.getBlob(columnIndex);. ¿Alguien tiene una idea de qué estoy haciendo mal?

Respuesta

4

creo que el cursor.moveToFirst() no ha sido llamado para que el cursor está lanzando android.database.CursorIndexOutOfBoundsException.

Antes de utilizar un cursor siempre se debe comprobar es el cursor está vacía o no llamando cursor.moveToFirst(). Esto también posicionará el cursor en la primera posición.

11

Extendí SimpleCursorAdapter, y aunque no utilicé ViewBinder aquí está mi código para usar una imagen almacenada como un blob en una base de datos sqlite en una vista de lista. Esto fue adaptado de un artículo que leí here.

Mi archivo de diseño para una fila es:

row_layout_two_line.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="@drawable/select_item"> 

<ImageView 
    android:id="@+id/pic" 
    android:layout_width="40dp" 
    android:layout_height="40dp" 
    android:layout_marginLeft="10dp" 
    android:contentDescription="@string/imagedesc" 
    android:src="@drawable/icon" 
    android:layout_gravity="center_vertical"> 
</ImageView> 

<LinearLayout 
    android:id="@+id/linearLayout0" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center_vertical" 
    android:orientation="vertical" > 

    <LinearLayout 
     android:id="@+id/linearLayout1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" > 

     <TextView 
      android:id="@+id/label" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="10dp" 
      android:text="@+id/label" 
      android:textStyle="bold" 
      android:textColor="#000" 
      android:textSize="20sp" > 
     </TextView> 

     <TextView 
      android:id="@+id/label1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="10dp" 
      android:text="@+id/label1" 
      android:textStyle="bold" 
      android:textColor="#000" 
      android:textSize="20sp" > 
     </TextView> 

    </LinearLayout> 

    <TextView 
     android:id="@+id/label2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="35dp" 
     android:text="@+id/label2" 
     android:textColor="#000" 
     android:textSize="15sp" > 
    </TextView> 
</LinearLayout> 

enter image description here

El código de llamada

... 
    adapter = null; 
    mCursor = search(); 

    startManagingCursor(mCursor); 
    // Now create a new list adapter bound to the cursor. 
    BaseAdapter adapter = new ImageCursorAdapter(this, // Context. 
      R.layout.row_layout_two_line, // Specify the row template 
                // to use (here, two 
                // columns bound to the 
                // two retrieved cursor 
                // rows). 
      mCursor, // Pass in the cursor to bind to. 
      // Array of cursor columns to bind to. 
      new String [] {"personImage", "firstName", "lastName", "title"}, 
      // Parallel array of which template objects to bind to those 
      // columns. 
      new int[] { R.id.pic, R.id.label, R.id.label1, R.id.label2 }); 


    // Bind to our new adapter. 
    setListAdapter(adapter); 
... 

ImageCursorAdapter.java

import android.content.Context; 
import android.database.Cursor; 
import android.graphics.BitmapFactory; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import android.widget.SimpleCursorAdapter; 
import android.widget.TextView; 

public class ImageCursorAdapter extends SimpleCursorAdapter { 

    private Cursor c; 
    private Context context; 

public ImageCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { 
    super(context, layout, c, from, to); 
    this.c = c; 
    this.context = context; 
} 

public View getView(int pos, View inView, ViewGroup parent) { 
     View v = inView; 
     if (v == null) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = inflater.inflate(R.layout.row_layout_two_line, null); 
     } 
     this.c.moveToPosition(pos);  
     String firstName = this.c.getString(this.c.getColumnIndex("firstName")); 
     String lastName = this.c.getString(this.c.getColumnIndex("lastName")); 
     String titleStr = this.c.getString(this.c.getColumnIndex("title")); 
     byte[] image = this.c.getBlob(this.c.getColumnIndex("personImage")); 
     ImageView iv = (ImageView) v.findViewById(R.id.pic); 
     if (image != null) { 
      // If there is no image in the database "NA" is stored instead of a blob 
      // test if there more than 3 chars "NA" + a terminating char if more than 
      // there is an image otherwise load the default 
      if(image.length > 3) 
      { 
       iv.setImageBitmap(BitmapFactory.decodeByteArray(image, 0, image.length)); 
      } 
      else 
      { 
       iv.setImageResource(R.drawable.icon); 
      } 
     } 
      TextView fname = (TextView) v.findViewById(R.id.label); 
      fname.setText(firstName); 

      TextView lname = (TextView) v.findViewById(R.id.label1); 
      lname.setText(lastName); 

      TextView title = (TextView) v.findViewById(R.id.label2); 
      title.setText(titleStr); 
     return(v); 
} 

}

Esto es lo que parece en el extremo

enter image description here

+2

¿Cuál es el punto de utilizar un SimpleCursorAdapter y diciéndole que la de las columnas, si voy a construir la Vista a mano en getView ???? – Radu

+0

@Radu como usted señala, es mejor que el propósito. – anthonymonori

1

lista de contactos usando ListView y SimpleCusrorAdapter con Contacto Fotos y Filtro/Búsqueda

He estado buscando una solución más simple y mi solución final es bastante más cercana a la que Daniel mencionó aquí, así que pensé que debería compartir la mía aquí. Estoy usando Fragment para mostrar Contactos del dispositivo como una lista de nombres con sus imágenes. El resultado es bastante similar al de Daniel, pero solo muestra nombres. Se puede mostrar más información fácilmente una vez que comprenda el código.

En mi caso estaba buscando nombres e imágenes de ContactsContract usando PHOTO_URI, así que no tuve que extender SimpleCursorAdapter como Daniel tuvo que hacerlo.

Mi ejemplo también incluye el filtrado de la lista de contactos como usuario escribe en SearchView para buscar un contacto

Tengo un fragmento llamado FragmentContacts y dos archivos de diseño, en primer lugar el diseño principal frag_contacts.xml y en segundo lugar para cada fila de contactos list_row_contact.

frag_contacts.xml

<LinearLayout 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" 
    android:orientation="vertical"> 
    <FrameLayout 
     android:layout_width="fill_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1" 
     android:background="@android:color/holo_blue_light" 
     android:padding="8dip"> 

     <android.support.v7.widget.SearchView 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:background="@android:color/white" 
      android:id="@+id/searchView"/> 
    </FrameLayout> 
    <LinearLayout 
     android:id="@+id/ll_contactList" 
     android:layout_width="fill_parent" 
     android:layout_height="0dp" 
     android:layout_weight="9" 
     android:orientation="vertical" > 
     <ListView 
      android:id="@+id/lv_ContactList" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:divider="#aaaaaa" 
      android:dividerHeight="1dp" > 
     </ListView> 
    </LinearLayout> 
</LinearLayout> 

list_row_contact.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:descendantFocusability="blocksDescendants"> 

    <FrameLayout 
     android:layout_height="match_parent" 
     android:layout_width="0dp" 
     android:layout_weight="1" 
     android:gravity="center"> 

     <ImageView 
      android:id="@+id/imgContact" 
      android:layout_width="35dip" 
      android:layout_height="35dip" 
      android:layout_gravity="center" 
      android:layout_margin="5dip" /> 
    </FrameLayout> 

    <TextView 
     android:id="@+id/contact_name" 
     android:layout_height="match_parent" 
     android:layout_width="0dp" 
     android:layout_weight="6" 
     android:gravity="center_vertical" 
     android:textSize="18sp" 
     android:paddingLeft="10dip"> 
    </TextView> 
</LinearLayout> 

FragmentContacts.java

public class FragmentContacts extends Fragment 
implements LoaderManager.LoaderCallbacks<Cursor>{ 
    private ListView lv_ContactList; 
    private SearchView searchView; 
    private SimpleCursorAdapter mCursorAdapter; 

    private static final String DISPLAY_NAME = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? Contacts.DISPLAY_NAME_PRIMARY : Contacts.DISPLAY_NAME; 

    private static final String[] contactsColumns = { Contacts._ID, Contacts.LOOKUP_KEY, DISPLAY_NAME, Contacts.PHOTO_URI }; 
    private final String contactsFilter = "(" +Contacts.HAS_PHONE_NUMBER+ "='1') AND (" + Contacts.IN_VISIBLE_GROUP + "='1')"; 
    private final String contactsSortOrder = DISPLAY_NAME + " COLLATE LOCALIZED ASC"; 

    private final static String[] listDisplayColumns = { DISPLAY_NAME, Contacts.PHOTO_URI }; 
    private final static int[] listDataViewIDs = { R.id.contact_name, R.id.imgContact }; 

    String[] mSelectionArgs; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.frag_contacts, null); 
     lv_ContactList = (ListView)view.findViewById(R.id.lv_ContactList); 
     searchView = (SearchView)view.findViewById(R.id.searchView); 
     return view; 
    } 

    @Override 
    public void onResume(){ 
     super.onResume(); 

     mCursorAdapter= new SimpleCursorAdapter(getActivity(), R.layout.list_row_contact, null, listDisplayColumns, listDataViewIDs, 0); 
     lv_ContactList.setAdapter(mCursorAdapter); 
     getLoaderManager().initLoader(0, null, this); 
     searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
      @Override 
      public boolean onQueryTextSubmit(String query) {return false;} 
      @Override 
      public boolean onQueryTextChange(String newText) { 
       if(newText.isEmpty()) mSelectionArgs = null; 
       else mSelectionArgs = new String[]{ "%"+newText.trim()+"%"}; 
       getLoaderManager().restartLoader(0, null, FragmentContacts.this); 
       return false; 
      } 
     }); 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     if(mSelectionArgs == null) 
      return new CursorLoader(getActivity(), Contacts.CONTENT_URI, contactsColumns, contactsFilter, null, contactsSortOrder); 
     else 
      return new CursorLoader(getActivity(), Contacts.CONTENT_URI, contactsColumns, contactsFilter + " AND (" + DISPLAY_NAME+" LIKE ?)", mSelectionArgs, contactsSortOrder); 
    } 
    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
     mCursorAdapter.swapCursor(data); 
    } 
    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     mCursorAdapter.swapCursor(null); 
    } 
} 
Cuestiones relacionadas