6

我試圖使用SimpleCursorAdapterViewBinder從數據庫獲取圖像並將其放入我的ListView項目視圖中。這裏是我的代碼: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); 
} 

我得到一個:

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

在執行byte[] byteArr = cursor.getBlob(columnIndex);。有沒有人有一個想法我做錯了什麼?

回答

4

我覺得cursor.moveToFirst()沒有被調用,所以光標拋出android.database.CursorIndexOutOfBoundsException.

使用cursor您應經常檢查之前是光標是空的或無法通過調用cursor.moveToFirst()。這也將光標定位在第一個位置。

11

我擴展了SimpleCursorAdapter,而我沒有使用ViewBinder,這裏是我的代碼,用於在列表視圖中將圖像作爲blob存儲在sqlite數據庫中。這是從我讀here的文章改編的。

對於行我的佈局文件是:

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

調用代碼

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

}

這裏是什麼樣子的

enter image description here

+2

什麼是使用SimpleCursorAdapter和列告訴它,如果我的點我將在getView中手動構建視圖???? – Radu

+0

@Radu就像你指出的那樣,它確實勝過了目的。 – anthonymonori

1

聯繫人列表使用ListView和SimpleCusrorAdapter與聯繫方式照片和濾波器的一端/搜索

我一直在尋找一個更簡單的解決方案和我的最終解決方案與丹尼爾在這裏提到的那個非常接近,所以我認爲我應該在這裏分享。我正在使用Fragment將設備聯繫人顯示爲其圖片名稱列表。結果與丹尼爾的非常相似,但只顯示名字。一旦你理解了代碼,更多的信息可以很容易地顯示出來。

在我的情況下,我使用PHOTO_URI從ContactsContract中獲取姓名和圖片,因此我不必按照Daniel的要求延長SimpleCursorAdapter

我的例子還包括過濾聯繫人作爲用戶類型的列表中SearchView找到一個接觸

我有一個名爲FragmentContacts和兩個佈局文件片段,第一主佈局frag_contacts.xml和第二爲每個聯繫人行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); 
    } 
} 
相關問題