19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.DataSetObserver;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Adapter that exposes data from a {@link android.database.Cursor Cursor} to a
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.widget.ListView ListView} widget. The Cursor must include
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a column named "_id" or this class will not work.
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class CursorAdapter extends BaseAdapter implements Filterable,
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CursorFilter.CursorFilterClient {
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean mDataValid;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean mAutoRequery;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected Cursor mCursor;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected Context mContext;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected int mRowIDColumn;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected ChangeObserver mChangeObserver;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected DataSetObserver mDataSetObserver = new MyDataSetObserver();
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected CursorFilter mCursorFilter;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected FilterQueryProvider mFilterQueryProvider;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constructor. The adapter will call requery() on the cursor whenever
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it changes so that the most recent data is always displayed.
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param c The cursor from which to get the data.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CursorAdapter(Context context, Cursor c) {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        init(context, c, true);
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constructor
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param c The cursor from which to get the data.
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param autoRequery If true the adapter will call requery() on the
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    cursor whenever it changes so the most recent
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    data is always displayed.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CursorAdapter(Context context, Cursor c, boolean autoRequery) {
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        init(context, c, autoRequery);
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void init(Context context, Cursor c, boolean autoRequery) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean cursorPresent = c != null;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAutoRequery = autoRequery;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCursor = c;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDataValid = cursorPresent;
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mChangeObserver = new ChangeObserver();
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cursorPresent) {
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.registerContentObserver(mChangeObserver);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.registerDataSetObserver(mDataSetObserver);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the cursor.
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the cursor.
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Cursor getCursor() {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursor;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getCount()
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1302c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public int getCount() {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCursor.getCount();
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getItem(int)
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1412c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public Object getItem(int position) {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.moveToPosition(position);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCursor;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getItemId(int)
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1532c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public long getItemId(int position) {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCursor.moveToPosition(position)) {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mCursor.getLong(mRowIDColumn);
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasStableIds() {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getView(int position, View convertView, ViewGroup parent) {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mDataValid) {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("this should only be called when the cursor is valid");
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mCursor.moveToPosition(position)) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("couldn't move cursor to position " + position);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View v;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (convertView == null) {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v = newView(mContext, mCursor, parent);
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v = convertView;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bindView(v, mContext, mCursor);
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return v;
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getDropDownView(int position, View convertView, ViewGroup parent) {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid) {
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.moveToPosition(position);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View v;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (convertView == null) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = newDropDownView(mContext, mCursor, parent);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = convertView;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bindView(v, mContext, mCursor);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return v;
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Makes a new view to hold the data pointed to by cursor.
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent The parent to which the new view is attached to
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the newly created view.
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract View newView(Context context, Cursor cursor, ViewGroup parent);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Makes a new drop down view to hold the data pointed to by cursor.
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent The parent to which the new view is attached to
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the newly created view.
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return newView(context, cursor, parent);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Bind an existing view to the data pointed to by cursor
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param view Existing view, returned earlier by newView
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void bindView(View view, Context context, Cursor cursor);
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the underlying cursor to a new cursor. If there is an existing cursor it will be
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * closed.
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor the new cursor to be used
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void changeCursor(Cursor cursor) {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cursor == mCursor) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCursor != null) {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.unregisterContentObserver(mChangeObserver);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.unregisterDataSetObserver(mDataSetObserver);
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.close();
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCursor = cursor;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cursor != null) {
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cursor.registerContentObserver(mChangeObserver);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cursor.registerDataSetObserver(mDataSetObserver);
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRowIDColumn = cursor.getColumnIndexOrThrow("_id");
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = true;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // notify the observers about the new cursor
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetChanged();
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRowIDColumn = -1;
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = false;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // notify the observers about the lack of a data set
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetInvalidated();
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Converts the cursor into a CharSequence. Subclasses should override this
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method to convert their results. The default implementation returns an
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * empty String for null values or the default String representation of
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the value.</p>
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor the cursor to convert to a CharSequence
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a CharSequence representing the value
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence convertToString(Cursor cursor) {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return cursor == null ? "" : cursor.toString();
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs a query with the specified constraint. This query is requested
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the filter attached to this adapter.
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The query is provided by a
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.widget.FilterQueryProvider}.
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If no provider is specified, the current cursor is not filtered and returned.
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * After this method returns the resulting cursor is passed to {@link #changeCursor(Cursor)}
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and the previous cursor is closed.
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method is always executed on a background thread, not on the
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application's main thread (or UI thread.)
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Contract: when constraint is null or empty, the original results,
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * prior to any filtering, must be returned.
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param constraint the constraint with which the query must be filtered
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a Cursor representing the results of the new query
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilter()
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilterQueryProvider()
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mFilterQueryProvider != null) {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mFilterQueryProvider.runQuery(constraint);
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursor;
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Filter getFilter() {
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCursorFilter == null) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursorFilter = new CursorFilter(this);
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursorFilter;
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the query filter provider used for filtering. When the
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider is null, no filtering occurs.
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the current filter query provider or null if it does not exist
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #runQueryOnBackgroundThread(CharSequence)
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public FilterQueryProvider getFilterQueryProvider() {
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFilterQueryProvider;
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the query filter provider used to filter the current Cursor.
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The provider's
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.widget.FilterQueryProvider#runQuery(CharSequence)}
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method is invoked when filtering is requested by a client of
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this adapter.
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param filterQueryProvider the filter query provider or null to remove it
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilterQueryProvider()
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #runQueryOnBackgroundThread(CharSequence)
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFilterQueryProvider(FilterQueryProvider filterQueryProvider) {
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFilterQueryProvider = filterQueryProvider;
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the {@link ContentObserver} on the cursor receives a change notification.
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The default implementation provides the auto-requery logic, but may be overridden by
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sub classes.
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see ContentObserver#onChange(boolean)
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onContentChanged() {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Config.LOGV) Log.v("Cursor", "Auto requerying " + mCursor + " due to update");
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = mCursor.requery();
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class ChangeObserver extends ContentObserver {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ChangeObserver() {
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(new Handler());
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean deliverSelfNotifications() {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onChange(boolean selfChange) {
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onContentChanged();
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class MyDataSetObserver extends DataSetObserver {
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onChanged() {
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = true;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetChanged();
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onInvalidated() {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = false;
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetInvalidated();
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
396