1f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein/*
2f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Copyright (C) 2011 Google Inc.
3f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Licensed to The Android Open Source Project.
4f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein *
5f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Licensed under the Apache License, Version 2.0 (the "License");
6f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * you may not use this file except in compliance with the License.
7f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * You may obtain a copy of the License at
8f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein *
9f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein *      http://www.apache.org/licenses/LICENSE-2.0
10f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein *
11f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Unless required by applicable law or agreed to in writing, software
12f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * distributed under the License is distributed on an "AS IS" BASIS,
13f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * See the License for the specific language governing permissions and
15f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * limitations under the License.
16f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */
17f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
18f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinpackage com.android.ex.photo.adapters;
19f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
20f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.content.Context;
21f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.database.Cursor;
228746927a945358bb9e515985a37cac7807261026Martin Hibdonimport android.support.v4.app.Fragment;
238746927a945358bb9e515985a37cac7807261026Martin Hibdonimport android.support.v4.app.FragmentManager;
24f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.util.Log;
25f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.util.SparseIntArray;
26f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.view.View;
27f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
28f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.provider.PhotoContract;
29f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
30f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport java.util.HashMap;
31f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
32f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein/**
33f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Page adapter for use with an BaseCursorLoader. Unlike other cursor adapters, this has no
34f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * observers for automatic refresh. Instead, it depends upon external mechanisms to provide
35f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * the update signal.
36f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */
37f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinpublic abstract class BaseCursorPagerAdapter extends BaseFragmentPagerAdapter {
38f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    private static final String TAG = "BaseCursorPagerAdapter";
39f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
40934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon    protected Context mContext;
41934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon    protected Cursor mCursor;
42934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon    protected int mRowIDColumn;
43f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /** Mapping of row ID to cursor position */
44934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon    protected SparseIntArray mItemPosition;
45f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /** Mapping of instantiated object to row ID */
46934bd9e0b4b3fcf7730325fa416b8c162141f7e9Martin Hibdon    protected final HashMap<Object, Integer> mObjectRowMap = new HashMap<Object, Integer>();
47f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
48f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
49f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Constructor that always enables auto-requery.
50f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     *
51f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @param c The cursor from which to get the data.
52f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @param context The context
53f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
54f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public BaseCursorPagerAdapter(Context context, FragmentManager fm, Cursor c) {
55f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        super(fm);
56f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        init(context, c);
57f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
58f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
59f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
60f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Makes a fragment for the data pointed to by the cursor
61f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     *
62f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @param context Interface to application's global information
63f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @param cursor The cursor from which to get the data. The cursor is already
64f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * moved to the correct position.
65f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @return the newly created fragment.
66f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
670c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein    public abstract Fragment getItem(Context context, Cursor cursor, int position);
68f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
690ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp    // TODO: This shouldn't just return null - maybe it needs to wait for a cursor to be supplied?
700ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp    //       See b/7103023
71f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    @Override
72f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public Fragment getItem(int position) {
730ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp        if (mCursor != null && moveCursorTo(position)) {
740c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein            return getItem(mContext, mCursor, position);
75f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
76f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        return null;
77f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
78f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
79f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    @Override
80f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public int getCount() {
810ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp        if (mCursor != null) {
82f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return mCursor.getCount();
83f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        } else {
84f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return 0;
85f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
86f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
87f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
88f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    @Override
89f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public Object instantiateItem(View container, int position) {
900ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp        if (mCursor == null) {
91f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            throw new IllegalStateException("this should only be called when the cursor is valid");
92f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
93f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
94f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        final Integer rowId;
95f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        if (moveCursorTo(position)) {
96f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            rowId = mCursor.getString(mRowIDColumn).hashCode();
97f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        } else {
98f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            rowId = null;
99f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
100f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
101f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        // Create the fragment and bind cursor data
102f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        final Object obj = super.instantiateItem(container, position);
103f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        if (obj != null) {
104f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            mObjectRowMap.put(obj, rowId);
105f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
106f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        return obj;
107f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
108f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
109f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    @Override
110f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public void destroyItem(View container, int position, Object object) {
111f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        mObjectRowMap.remove(object);
112f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
113f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        super.destroyItem(container, position, object);
114f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
115f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
116f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    @Override
117f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public int getItemPosition(Object object) {
118f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        final Integer rowId = mObjectRowMap.get(object);
119f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        if (rowId == null || mItemPosition == null) {
120f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return POSITION_NONE;
121f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
122f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
123f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        final int position = mItemPosition.get(rowId, POSITION_NONE);
124f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        return position;
125f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
126f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
127f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
128f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @return true if data is valid
129f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
130f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public boolean isDataValid() {
1310ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp        return mCursor != null;
132f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
133f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
134f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
135f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Returns the cursor.
136f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
137f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public Cursor getCursor() {
138f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        return mCursor;
139f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
140f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
141f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
142f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Returns the data item associated with the specified position in the data set.
143f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
144f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public Object getDataItem(int position) {
1450ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp        if (mCursor != null && moveCursorTo(position)) {
146f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return mCursor;
147f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        } else {
148f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return null;
149f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
150f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
151f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
152f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
153f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Returns the row id associated with the specified position in the list.
154f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
155f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public long getItemId(int position) {
1560ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp        if (mCursor != null && moveCursorTo(position)) {
157f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return mCursor.getString(mRowIDColumn).hashCode();
158f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        } else {
159f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return 0;
160f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
161f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
162f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
163f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
164f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Swap in a new Cursor, returning the old Cursor.
165f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     *
166f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @param newCursor The new cursor to be used.
167f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @return Returns the previously set Cursor, or null if there was not one.
168f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * If the given new Cursor is the same instance is the previously set
169f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Cursor, null is also returned.
170f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
171f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public Cursor swapCursor(Cursor newCursor) {
172f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        if (Log.isLoggable(TAG, Log.VERBOSE)) {
173f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            Log.v(TAG, "swapCursor old=" + (mCursor == null ? -1 : mCursor.getCount()) +
174f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein                    "; new=" + (newCursor == null ? -1 : newCursor.getCount()));
175f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
176f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
177f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        if (newCursor == mCursor) {
178f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return null;
179f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
180f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        Cursor oldCursor = mCursor;
181f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        mCursor = newCursor;
182f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        if (newCursor != null) {
183f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            mRowIDColumn = newCursor.getColumnIndex(PhotoContract.PhotoViewColumns.URI);
184f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        } else {
185f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            mRowIDColumn = -1;
186f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
187f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
188f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        setItemPosition();
189f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        notifyDataSetChanged();     // notify the observers about the new cursor
190f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        return oldCursor;
191f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
192f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
193f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
194f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Converts the cursor into a CharSequence. Subclasses should override this
195f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * method to convert their results. The default implementation returns an
196f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * empty String for null values or the default String representation of
197f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * the value.
198f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     *
199f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @param cursor the cursor to convert to a CharSequence
200f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @return a CharSequence representing the value
201f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
202f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    public CharSequence convertToString(Cursor cursor) {
203f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        return cursor == null ? "" : cursor.toString();
204f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
205f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
206f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    @Override
207f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    protected String makeFragmentName(int viewId, int index) {
208f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        if (moveCursorTo(index)) {
209f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return "android:pager:" + viewId + ":" + mCursor.getString(mRowIDColumn).hashCode();
210f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        } else {
211f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return super.makeFragmentName(viewId, index);
212f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
213f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
214f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
215f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
216f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Moves the cursor to the given position
217f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     *
218f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * @return {@code true} if the cursor's position was set. Otherwise, {@code false}.
219f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
220f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    private boolean moveCursorTo(int position) {
221f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        if (mCursor != null && !mCursor.isClosed()) {
222f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return mCursor.moveToPosition(position);
223f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
224f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        return false;
225f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
226f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
227f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
228f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Initialize the adapter.
229f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
230f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    private void init(Context context, Cursor c) {
231f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        boolean cursorPresent = c != null;
232f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        mCursor = c;
233f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        mContext = context;
234f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        mRowIDColumn = cursorPresent
235f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein                ? mCursor.getColumnIndex(PhotoContract.PhotoViewColumns.URI) : -1;
236f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
237f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
238f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    /**
239f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * Sets the {@link #mItemPosition} instance variable with the current mapping of
240f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     * row id to cursor position.
241f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein     */
242f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    private void setItemPosition() {
2430ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp        if (mCursor == null || mCursor.isClosed()) {
244f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            mItemPosition = null;
245f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            return;
246f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
247f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
248f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        SparseIntArray itemPosition = new SparseIntArray(mCursor.getCount());
249f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
250f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        mCursor.moveToPosition(-1);
251f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        while (mCursor.moveToNext()) {
252f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            final int rowId = mCursor.getString(mRowIDColumn).hashCode();
253f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            final int position = mCursor.getPosition();
254f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein
255f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein            itemPosition.append(rowId, position);
256f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        }
257f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein        mItemPosition = itemPosition;
258f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein    }
259f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein}
260