1

I have a listview which loads its data from sqlite database. Each row in listview has image , textview and a checkbox. The sqlitedatabase rows has image and text data + some other columns.

My question is can I bind my listview with the database so that all rows will be loaded with required data automatically. (image + textview) There are examples to bind a simple list of textviews. What about complex rows ? Also there are few spinners which can filter the data in list depending on its value. (Which act as a WHERE clause on my DB)

Currently I am managing this all by generating the view for my custom adapter for each row. So each time I query database and populate data. I hold the last listview results , make a newer results based on actions/conditions like spinner values, then notifydatachanged to adapter to load my new results.

To add features like DELETE , ADD , SEARCH -- I have to manage it all using collections.

Is there any simple way of doing this ? As if the db is large then the approach of holding such huge set of results in memory is not good. And is painful for managing it. Thanks.

1
  • And to mention a issue if you add a checkbox in your listview row, you do not get a click event on list items. You need to add listener to individual views in row. So how to get a normal click on list item ? Commented Dec 23, 2010 at 16:36

2 Answers 2

2

Here is my example for row, constructed from two records from db + image (at current - one image for any row, but it can be improved for specific image from db):

    public class DomainAdapter extends SimpleCursorAdapter{
    private Cursor dataCursor;

    private LayoutInflater mInflater;
    ....

    public DomainAdapter(Context context, int layout, Cursor dataCursor, String[] from,
            int[] to) {
        super(context, layout, dataCursor, from, to);
            this.dataCursor = dataCursor;
            mInflater = LayoutInflater.from(context);
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        // A ViewHolder keeps references to children views to avoid unneccessary calls
        // to findViewById() on each row.
        ViewHolder holder;

        // When convertView is not null, we can reuse it directly, there is no need
        // to reinflate it. We only inflate a new View when the convertView supplied
        // by ListView is null.
        if (convertView == null) {
            convertView = mInflater.inflate(layout, null);

            // Creates a ViewHolder and store references to the two children views
            // we want to bind data to.
            holder = new ViewHolder();
            holder.text1 = (TextView) convertView.findViewById(R.id.test_track);
            holder.text2 = (TextView) convertView.findViewById(R.id.test_band);
            holder.icon = (ImageView) convertView.findViewById(R.id.test_artwork);

            convertView.setTag(holder);
        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();
        }

        // Bind the data efficiently with the holder.
        // Cursor to current item
        dataCursor.moveToPosition(position);
        int title_index = dataCursor.getColumnIndex(fields[0]); 
        String title = dataCursor.getString(title_index);

        int description_index = dataCursor.getColumnIndex(fields[1]); 
        String description = dataCursor.getString(description_index);

        holder.text1.setText(title);
        holder.text2.setText(description);
        holder.icon.setImageResource(R.drawable.alert_dialog_icon);

        return convertView;
    }

    static class ViewHolder {
        TextView text1;
        TextView text2;
        ImageView icon;
    }
}

and using this adapter:

databaseListAdapter = new DomainAdapter(this, 
                R.layout.test_layout, 
                databaseCursor, 
                new String[] {"title", "description"}, 
                new int[] { R.id.test_track, R.id.test_track });
databaseListAdapter.notifyDataSetChanged();
DomainView.setAdapter(databaseListAdapter);

and layout:

<?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="64dip"
    android:padding="6dip">

    <TextView
        android:id="@+id/test_band"  
        android:layout_width="fill_parent" 
        android:layout_height="26dip" 

        android:layout_below="@+id/test_track"
        android:layout_alignLeft="@id/test_track"
        android:layout_alignParentBottom="true"

        android:gravity="top" />

    <TextView
        android:id="@id/test_track"  
        android:layout_marginLeft="6dip"
        android:layout_width="fill_parent"
        android:layout_height="26dip"

        android:layout_toRightOf="@+id/test_artwork"

        android:textAppearance="?android:attr/textAppearanceMedium"
        android:gravity="bottom" />

    <ImageView
        android:id="@id/test_artwork"
        android:layout_width="56dip"
        android:layout_height="56dip"
        android:layout_gravity="center_vertical" />

</RelativeLayout>
Sign up to request clarification or add additional context in comments.

3 Comments

Hi, can you expand farther on your example. I'm not sure how to use the "data." variable. Thnx!
I'm very sorry! When I wrote this code, I have renamed some variables. data - is the Cursor. I've fixed errors, thank you for question.
Can you see what I have wrong (think its my cursor return). I posted the Q over here so you can get credit. Thnx!!
0

My question is can I bind my listview with the database so that all rows will be loaded with required data automatically. (image + textview) There are examples to bind a simple list of textviews. What about complex rows ?

Yes, you can do a Cursor to complex view mapping by implementing your own CursorAdapter and overriding the bindView().

1 Comment

It's not necessary to extend CursorAdapter; you can add a ViewBinder to achieve more-or-less the same effect as overriding bindView. I have a recent blog post that includes a sample ViewBinder. (The example uses a Spinner and SimpleAdapter, but the technique should work with ListView and SimpleCursorAdapter.) See outofwhatbox.com/blog/2010/12/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.