CursorAdapter.java revision 69e87f9b43b82b9a0f8a0fbc1c41251bbea212f9
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    /**
83451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * If set the adapter will call requery() on the cursor whenever a content change
84451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * notification is delivered. Implies {@link #FLAG_REGISTER_CONTENT_OBSERVER}
85451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     */
86451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    public static final int FLAG_AUTO_REQUERY = 0x01;
87451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
88451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    /**
89451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * If set the adapter will register a content observer on the cursor and will call
90451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * {@link #onContentChanged()} when a notification comes in.
91451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     */
92451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    public static final int FLAG_REGISTER_CONTENT_OBSERVER = 0x02;
93451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
94451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    /**
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constructor. The adapter will call requery() on the cursor whenever
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it changes so that the most recent data is always displayed.
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param c The cursor from which to get the data.
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CursorAdapter(Context context, Cursor c) {
102451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        init(context, c, FLAG_AUTO_REQUERY);
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constructor
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param c The cursor from which to get the data.
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param autoRequery If true the adapter will call requery() on the
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    cursor whenever it changes so the most recent
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    data is always displayed.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CursorAdapter(Context context, Cursor c, boolean autoRequery) {
11469e87f9b43b82b9a0f8a0fbc1c41251bbea212f9Jeff Hamilton        init(context, c, autoRequery ? FLAG_AUTO_REQUERY : FLAG_REGISTER_CONTENT_OBSERVER);
115451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    }
116451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
117451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    /**
118451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * Constructor
119451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * @param c The cursor from which to get the data.
120451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * @param context The context
121451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * @param flags flags used to determine the behavior of the adapter
122451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     */
123451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    public CursorAdapter(Context context, Cursor c, int flags) {
124451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        init(context, c, flags);
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void init(Context context, Cursor c, boolean autoRequery) {
12869e87f9b43b82b9a0f8a0fbc1c41251bbea212f9Jeff Hamilton        init(context, c, autoRequery ? FLAG_AUTO_REQUERY : FLAG_REGISTER_CONTENT_OBSERVER);
129451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    }
130451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
131451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    protected void init(Context context, Cursor c, int flags) {
132451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        if ((flags & FLAG_AUTO_REQUERY) == FLAG_AUTO_REQUERY) {
133451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            flags |= FLAG_REGISTER_CONTENT_OBSERVER;
134451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mAutoRequery = true;
135451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        } else {
136451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mAutoRequery = false;
137451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean cursorPresent = c != null;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCursor = c;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDataValid = cursorPresent;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
143451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        if ((flags & FLAG_REGISTER_CONTENT_OBSERVER) == FLAG_REGISTER_CONTENT_OBSERVER) {
144451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mChangeObserver = new ChangeObserver();
145451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        } else {
146451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mChangeObserver = null;
147451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        }
148451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cursorPresent) {
150451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            if (mChangeObserver != null) c.registerContentObserver(mChangeObserver);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.registerDataSetObserver(mDataSetObserver);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the cursor.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the cursor.
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Cursor getCursor() {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursor;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getCount()
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1662c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public int getCount() {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCursor.getCount();
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getItem(int)
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1772c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public Object getItem(int position) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.moveToPosition(position);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCursor;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getItemId(int)
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1892c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public long getItemId(int position) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCursor.moveToPosition(position)) {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mCursor.getLong(mRowIDColumn);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasStableIds() {
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getView(int position, View convertView, ViewGroup parent) {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mDataValid) {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("this should only be called when the cursor is valid");
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mCursor.moveToPosition(position)) {
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("couldn't move cursor to position " + position);
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View v;
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (convertView == null) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v = newView(mContext, mCursor, parent);
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v = convertView;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bindView(v, mContext, mCursor);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return v;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getDropDownView(int position, View convertView, ViewGroup parent) {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid) {
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.moveToPosition(position);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View v;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (convertView == null) {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = newDropDownView(mContext, mCursor, parent);
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = convertView;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bindView(v, mContext, mCursor);
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return v;
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Makes a new view to hold the data pointed to by cursor.
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent The parent to which the new view is attached to
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the newly created view.
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract View newView(Context context, Cursor cursor, ViewGroup parent);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Makes a new drop down view to hold the data pointed to by cursor.
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent The parent to which the new view is attached to
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the newly created view.
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return newView(context, cursor, parent);
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Bind an existing view to the data pointed to by cursor
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param view Existing view, returned earlier by newView
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void bindView(View view, Context context, Cursor cursor);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the underlying cursor to a new cursor. If there is an existing cursor it will be
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * closed.
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor the new cursor to be used
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void changeCursor(Cursor cursor) {
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cursor == mCursor) {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCursor != null) {
285451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            if (mChangeObserver != null) mCursor.unregisterContentObserver(mChangeObserver);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.unregisterDataSetObserver(mDataSetObserver);
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.close();
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCursor = cursor;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cursor != null) {
291451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            if (mChangeObserver != null) cursor.registerContentObserver(mChangeObserver);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cursor.registerDataSetObserver(mDataSetObserver);
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRowIDColumn = cursor.getColumnIndexOrThrow("_id");
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = true;
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // notify the observers about the new cursor
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetChanged();
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRowIDColumn = -1;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = false;
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // notify the observers about the lack of a data set
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetInvalidated();
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Converts the cursor into a CharSequence. Subclasses should override this
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method to convert their results. The default implementation returns an
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * empty String for null values or the default String representation of
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the value.</p>
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor the cursor to convert to a CharSequence
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a CharSequence representing the value
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence convertToString(Cursor cursor) {
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return cursor == null ? "" : cursor.toString();
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs a query with the specified constraint. This query is requested
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the filter attached to this adapter.
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The query is provided by a
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.widget.FilterQueryProvider}.
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If no provider is specified, the current cursor is not filtered and returned.
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * After this method returns the resulting cursor is passed to {@link #changeCursor(Cursor)}
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and the previous cursor is closed.
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method is always executed on a background thread, not on the
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application's main thread (or UI thread.)
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Contract: when constraint is null or empty, the original results,
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * prior to any filtering, must be returned.
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param constraint the constraint with which the query must be filtered
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a Cursor representing the results of the new query
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilter()
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilterQueryProvider()
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mFilterQueryProvider != null) {
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mFilterQueryProvider.runQuery(constraint);
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursor;
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Filter getFilter() {
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCursorFilter == null) {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursorFilter = new CursorFilter(this);
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursorFilter;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the query filter provider used for filtering. When the
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider is null, no filtering occurs.
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the current filter query provider or null if it does not exist
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #runQueryOnBackgroundThread(CharSequence)
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public FilterQueryProvider getFilterQueryProvider() {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFilterQueryProvider;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the query filter provider used to filter the current Cursor.
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The provider's
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.widget.FilterQueryProvider#runQuery(CharSequence)}
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method is invoked when filtering is requested by a client of
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this adapter.
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param filterQueryProvider the filter query provider or null to remove it
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilterQueryProvider()
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #runQueryOnBackgroundThread(CharSequence)
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFilterQueryProvider(FilterQueryProvider filterQueryProvider) {
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFilterQueryProvider = filterQueryProvider;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the {@link ContentObserver} on the cursor receives a change notification.
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The default implementation provides the auto-requery logic, but may be overridden by
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sub classes.
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see ContentObserver#onChange(boolean)
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onContentChanged() {
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Config.LOGV) Log.v("Cursor", "Auto requerying " + mCursor + " due to update");
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = mCursor.requery();
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class ChangeObserver extends ContentObserver {
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ChangeObserver() {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(new Handler());
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean deliverSelfNotifications() {
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onChange(boolean selfChange) {
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onContentChanged();
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class MyDataSetObserver extends DataSetObserver {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onChanged() {
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = true;
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetChanged();
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onInvalidated() {
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = false;
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetInvalidated();
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
432