6

Tôi đang cố gắng sử dụng một SimpleCursorAdapter với một ViewBinder để lấy hình ảnh từ cơ sở dữ liệu và đặt nó vào chế độ xem mục ListView của tôi. Đây là mã của tôi:Hình ảnh trong 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); 
} 

Tôi nhận được một:

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

trong khi thực hiện byte[] byteArr = cursor.getBlob(columnIndex);. Có ai có một ý tưởng những gì tôi làm sai?

Trả lời

4

Tôi nghĩ rằng cursor.moveToFirst() chưa được gọi là để con được ném android.database.CursorIndexOutOfBoundsException.

Trước khi sử dụng một cursor bạn nên luôn luôn kiểm tra là con trỏ rỗng hay không bằng cách gọi cursor.moveToFirst(). Điều này cũng sẽ định vị con trỏ ở vị trí đầu tiên.

11

Tôi đã mở rộng SimpleCursorAdapter và trong khi tôi không sử dụng ViewBinder thì đây là mã của tôi để sử dụng hình ảnh được lưu trữ dưới dạng blob trong cơ sở dữ liệu sqlite trong listview. Điều này đã được điều chỉnh từ một bài báo tôi đọc here.

file layout của tôi cho một hàng là:

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

Mã gọi

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

}

Đây là những gì nó trông giống như vào cuối

enter image description here

+2

điểm của việc sử dụng một SimpleCursorAdapter và nói với nó từ cột, nếu tôi là gì sẽ xây dựng View bằng tay trong getView ???? – Radu

+0

@Radu khi bạn chỉ ra, nó không đánh bại mục đích. – anthonymonori

1

Danh sách liên hệ sử dụng ListView và SimpleCusrorAdapter với Liên Ảnh và Lọc/Tìm kiếm

Tôi đã tìm kiếm một giải pháp đơn giản hơn và giải pháp cuối cùng của tôi là khá gần với một Daniel đã đề cập ở đây vì vậy tôi nghĩ rằng tôi nên chia sẻ của tôi ở đây. Tôi đang sử dụng Phân đoạn để hiển thị Danh bạ thiết bị dưới dạng danh sách tên có hình ảnh của họ. Kết quả là khá giống với của Daniel nhưng chỉ hiển thị tên. Thông tin thêm có thể được hiển thị rất dễ dàng khi bạn hiểu mã.

Trong trường hợp của tôi, tôi đã tìm nạp tên và hình ảnh từ ContactsContract sử dụng PHOTO_URI vì vậy tôi không phải gia hạn SimpleCursorAdapter như Daniel phải làm.

Ví dụ của tôi cũng bao gồm lọc danh sách các địa chỉ liên lạc như các loại dùng trong SearchView để tìm một số liên lạc

Tôi có một Fragment gọi FragmentContacts và hai tập tin Layout, đầu tiên Layout chính frag_contacts.xml và thứ hai cho mỗi hàng tiếp xúc 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); 
    } 
} 
Các vấn đề liên quan