how do i create a custom cursor adapter for a listview for use with images and text? how do i create a custom cursor adapter for a listview for use with images and text? android android

how do i create a custom cursor adapter for a listview for use with images and text?


Will,

I've actually implemented something incredibly similar to what you are looking for. Here is my implementation.

import android.content.Context;import android.content.SharedPreferences;import android.content.res.Resources;import android.database.Cursor;import android.preference.PreferenceManager;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.CursorAdapter;import android.widget.ImageView;import android.widget.TextView;public class ItemAdapter extends CursorAdapter {    private LayoutInflater mLayoutInflater;    private Context mContext;    public ItemAdapter(Context context, Cursor c) {        super(context, c);        mContext = context;        mLayoutInflater = LayoutInflater.from(context);     }    @Override    public View newView(Context context, Cursor cursor, ViewGroup parent) {        View v = mLayoutInflater.inflate(R.layout.items_row, parent, false);        return v;    }    /**     * @author will     *      * @param   v     *          The view in which the elements we set up here will be displayed.     *      * @param   context     *          The running context where this ListView adapter will be active.     *      * @param   c     *          The Cursor containing the query results we will display.     */    @Override    public void bindView(View v, Context context, Cursor c) {        String title = c.getString(c.getColumnIndexOrThrow(ItemDbAdapter.KEY_TITLE));        String date = c.getString(c.getColumnIndexOrThrow(ItemDbAdapter.KEY_DATE));        String imagePath = c.getString(c.getColumnIndexOrThrow(ItemDbAdapter.KEY_IMG));        int deletion = c.getInt(c.getColumnIndexOrThrow(ItemDbAdapter.KEY_DELETION));        int priority = c.getInt(c.getColumnIndexOrThrow(ItemDbAdapter.KEY_PRIORITY));        /**         * Next set the title of the entry.         */        TextView title_text = (TextView) v.findViewById(R.id.item_text);        if (title_text != null) {            title_text.setText(title);        }        /**         * Set Date         */        TextView date_text = (TextView) v.findViewById(R.id.item_date);        if (date_text != null) {            date_text.setText(date);        }               /**         * Decide if we should display the paper clip icon denoting image attachment         */        ImageView item_image = (ImageView) v.findViewById(R.id.item_attachment);        item_image.setVisibility(ImageView.INVISIBLE);        if (imagePath != null && imagePath.length() != 0 && item_image != null) {            item_image.setVisibility(ImageView.VISIBLE);        }        /**         * Decide if we should display the deletion indicator         */        ImageView del_image = (ImageView) v.findViewById(R.id.item_deletion);        del_image.setVisibility(ImageView.INVISIBLE);        if (deletion == 1) {            del_image.setVisibility(ImageView.VISIBLE);        }    }}

XML just incase...

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"    android:background="@drawable/list_bg">    <LinearLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:orientation="vertical">        <TextView android:id="@+id/item_text"            android:layout_width="200dp"            android:layout_height="wrap_content"            android:lines="1"            android:scrollHorizontally="true"            android:ellipsize="end"            android:paddingLeft="2sp"            android:paddingTop="2sp"            android:textSize="18sp"            android:textStyle="bold"            android:shadowColor="#90909090"            android:shadowDx="1.0"            android:shadowDy="1.0"            android:shadowRadius="1.0"/>        <TextView android:id="@+id/item_date"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textSize="12sp"            android:textColor="#FF808080"            android:paddingLeft="2sp"            android:paddingTop="2sp"/>    </LinearLayout>    <ImageView android:id="@+id/item_deletion"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/deletion"        android:visibility="invisible"        android:layout_centerVertical="true"        android:layout_alignParentRight="true"        android:paddingRight="5sp"/>    <ImageView android:id="@+id/item_attachment"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/attachment"        android:visibility="invisible"        android:layout_centerVertical="true"        android:layout_toLeftOf="@id/item_deletion"/></RelativeLayout>

This displays two rows of text and up to 2 images to the right of the text depending on certain conditions.

I hope this can give you a basis to work from!

Good luck :]


Check what I have done:BTW: CheckpointsView.getImageResId() returns a valid drawable reference

public class CheckpointCursorAdapter extends ResourceCursorAdapter {    private int layoutType = 0;    public static final int BLOTTER = 1;    public static final int DAY = 2;    public static final int MONTH = 3;    public static final int OVERVIEW = 4;    public static final int LAYOUT_ID = R.layout.checkpoint_row;    public CheckpointCursorAdapter(Context context, int layoutType, Cursor cursor) {        super(context, LAYOUT_ID, cursor);        this.layoutType = layoutType;    }    @Override    public View newView(Context context, Cursor cur, ViewGroup parent) {        LayoutInflater li = (LayoutInflater) context                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);        return li.inflate(LAYOUT_ID, parent, false);    }    @Override    public void bindView(View view, Context context, Cursor cursor) {        TextView tvListText = (TextView) view.findViewById(R.id.txtCheckPoint);        Date dt = new Date(cursor.getLong(cursor.getColumnIndex(DatabaseHelper.KEY_CHECKPOINT)));        switch (layoutType) {            case BLOTTER:                tvListText.setText(dt.toLocaleString());                ((ImageView) view.findViewById(R.id.imgCheckpointInOut))                        .setImageResource(CheckpointsView.getImageResId(cursor.getCount()                                - cursor.getPosition()));                break;            case DAY:                tvListText.setText(new SimpleDateFormat("HH:mm:ss").format(dt));                ((ImageView) view.findViewById(R.id.imgCheckpointInOut))                        .setImageResource(CheckpointsView.getImageResId(cursor.getPosition() + 1));                break;            case MONTH:                tvListText.setText(new SimpleDateFormat("MMM dd HH:mm:ss").format(dt));                ((ImageView) view.findViewById(R.id.imgCheckpointInOut))                        .setImageResource(CheckpointsView.getImageResId(cursor.getPosition() + 1));                break;            case OVERVIEW:                break;        }    }}

And the XML just in case

<?xml version="1.0" encoding="utf-8"?>

<TextView android:id="@+id/txtCheckPoint"    android:layout_width="wrap_content" android:layout_height="wrap_content"    android:textSize="20dp" android:padding="8dp" android:textStyle="bold"></TextView><LinearLayout android:layout_width="fill_parent"    android:layout_height="wrap_content" android:orientation="horizontal"    android:gravity="right" android:layout_weight="1"    android:layout_marginRight="8px">    <TextView android:id="@+id/txtTotalHours"    android:layout_width="wrap_content" android:layout_height="wrap_content"    android:textSize="20dp" android:padding="8dp" android:paddingRight="12dp"></TextView>    <TextView android:id="@+id/txtHourBalanceRow"        android:layout_width="wrap_content" android:layout_height="wrap_content"        android:textSize="12dp" android:padding="8dp">    </TextView>    <ImageView android:id="@+id/imgCheckpointInOut"        android:layout_width="wrap_content" android:layout_height="wrap_content"        android:src="@drawable/black_clock" /></LinearLayout>

You can check the whole code at:http://code.google.com/p/droidtimesheet/


Adding images and text is not specific to CursorAdapter; you use the same technique for any kind of adapter. You can create a layout for your row and inflate it inside your getView method. The APIDemos sample project, contained in the Android SDK android-sdk-PLATFORM/samples/android-XY/ApiDemos folder, does what you want. You can find the row definitons in list_item_icon_text.xml. Here is copy of file content (w/o the license).

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal"    android:layout_width="match_parent"    android:layout_height="match_parent">    <ImageView android:id="@+id/icon"        android:layout_width="48dip"        android:layout_height="48dip" />    <TextView android:id="@+id/text"        android:layout_gravity="center_vertical"        android:layout_width="0dip"        android:layout_weight="1.0"        android:layout_height="wrap_content" /></LinearLayout>