6

Sto cercando di utilizzare uno SimpleCursorAdapter con un ViewBinder per ottenere un'immagine dal database e inserirla nella vista dell'oggetto ListView. Ecco il mio codice:Immagini in 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); 
} 

sto ottenendo un:

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

durante l'esecuzione byte[] byteArr = cursor.getBlob(columnIndex);. Qualcuno ha un'idea di cosa sto sbagliando?

risposta

4

penso che il cursor.moveToFirst() non è stato chiamato così il cursore sta gettando android.database.CursorIndexOutOfBoundsException.

Prima di usare un cursor si dovrebbe sempre verificare è il cursore è vuota o non chiamando cursor.moveToFirst(). Questo posizionerà anche il cursore nella prima posizione.

11

Ho esteso SimpleCursorAdapter e anche se non ho utilizzato un ViewBinder, ecco il mio codice per l'utilizzo di un'immagine memorizzata come un BLOB in un database SQLite in un listview. Questo è stato adattato da un articolo che ho letto here.

mio file di layout per una riga è:

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

Il codice chiamante

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

}

Ecco come si presenta alla fine

enter image description here

+2

Qual è il punto di utilizzare un SimpleCursorAdapter e dirgli il da colonne, se io costruirò la View a mano in getView ???? – Radu

+0

@Radu come si sottolinea, batte lo scopo. – anthonymonori

1

elenco contatti utilizzando ListView e SimpleCusrorAdapter con Contatto Foto e Filtro/Ricerca

Ero alla ricerca di una soluzione più semplice e la mia soluzione finale è abbastanza vicina a quella che Daniel ha menzionato qui, quindi ho pensato che dovrei condividere il mio qui. Sto usando Fragment per mostrare i contatti del dispositivo come un elenco di nomi con le loro immagini. Il risultato è molto simile a quello di Daniel ma mostra solo nomi. Ulteriori informazioni possono essere visualizzate molto facilmente una volta compreso il codice.

Nel mio caso stavo recuperando nomi e immagini da ContactsContract utilizzando PHOTO_URI, quindi non dovevo estendere SimpleCursorAdapter come Daniel doveva.

Il mio esempio include anche filtrare l'elenco dei contatti come tipi di utente in SearchView per trovare un contatto

Ho un frammento chiamato FragmentContacts due file e di layout, prima il layout principale frag_contacts.xml e secondo per ogni riga contatto 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); 
    } 
} 
Problemi correlati