Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package android.app; |
| 18 | |
| 19 | import android.os.Bundle; |
| 20 | import android.os.Handler; |
| 21 | import android.view.LayoutInflater; |
| 22 | import android.view.View; |
| 23 | import android.view.ViewGroup; |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 24 | import android.view.animation.AnimationUtils; |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 25 | import android.widget.AdapterView; |
| 26 | import android.widget.ListAdapter; |
| 27 | import android.widget.ListView; |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 28 | import android.widget.TextView; |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 29 | |
| 30 | /** |
Dianne Hackborn | dd913a5 | 2010-07-22 12:17:04 -0700 | [diff] [blame] | 31 | * A fragment that displays a list of items by binding to a data source such as |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 32 | * an array or Cursor, and exposes event handlers when the user selects an item. |
| 33 | * <p> |
Dianne Hackborn | dd913a5 | 2010-07-22 12:17:04 -0700 | [diff] [blame] | 34 | * ListFragment hosts a {@link android.widget.ListView ListView} object that can |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 35 | * be bound to different data sources, typically either an array or a Cursor |
| 36 | * holding query results. Binding, screen layout, and row layout are discussed |
| 37 | * in the following sections. |
| 38 | * <p> |
| 39 | * <strong>Screen Layout</strong> |
| 40 | * </p> |
| 41 | * <p> |
Dianne Hackborn | dd913a5 | 2010-07-22 12:17:04 -0700 | [diff] [blame] | 42 | * ListFragment has a default layout that consists of a single list view. |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 43 | * However, if you desire, you can customize the fragment layout by returning |
| 44 | * your own view hierarchy from {@link #onCreateView}. |
Dianne Hackborn | dd913a5 | 2010-07-22 12:17:04 -0700 | [diff] [blame] | 45 | * To do this, your view hierarchy <em>must</em> contain a ListView object with the |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 46 | * id "@android:id/list" (or {@link android.R.id#list} if it's in code) |
| 47 | * <p> |
| 48 | * Optionally, your view hierarchy can contain another view object of any type to |
| 49 | * display when the list view is empty. This "empty list" notifier must have an |
| 50 | * id "android:empty". Note that when an empty view is present, the list view |
| 51 | * will be hidden when there is no data to display. |
| 52 | * <p> |
Dianne Hackborn | dd913a5 | 2010-07-22 12:17:04 -0700 | [diff] [blame] | 53 | * The following code demonstrates an (ugly) custom list layout. It has a list |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 54 | * with a green background, and an alternate red "no data" message. |
| 55 | * </p> |
| 56 | * |
| 57 | * <pre> |
| 58 | * <?xml version="1.0" encoding="utf-8"?> |
| 59 | * <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| 60 | * android:orientation="vertical" |
| 61 | * android:layout_width="match_parent" |
| 62 | * android:layout_height="match_parent" |
| 63 | * android:paddingLeft="8dp" |
| 64 | * android:paddingRight="8dp"> |
| 65 | * |
| 66 | * <ListView android:id="@id/android:list" |
| 67 | * android:layout_width="match_parent" |
| 68 | * android:layout_height="match_parent" |
| 69 | * android:background="#00FF00" |
| 70 | * android:layout_weight="1" |
| 71 | * android:drawSelectorOnTop="false"/> |
| 72 | * |
| 73 | * <TextView android:id="@id/android:empty" |
| 74 | * android:layout_width="match_parent" |
| 75 | * android:layout_height="match_parent" |
| 76 | * android:background="#FF0000" |
| 77 | * android:text="No data"/> |
| 78 | * </LinearLayout> |
| 79 | * </pre> |
| 80 | * |
| 81 | * <p> |
| 82 | * <strong>Row Layout</strong> |
| 83 | * </p> |
| 84 | * <p> |
| 85 | * You can specify the layout of individual rows in the list. You do this by |
| 86 | * specifying a layout resource in the ListAdapter object hosted by the fragment |
| 87 | * (the ListAdapter binds the ListView to the data; more on this later). |
| 88 | * <p> |
| 89 | * A ListAdapter constructor takes a parameter that specifies a layout resource |
| 90 | * for each row. It also has two additional parameters that let you specify |
| 91 | * which data field to associate with which object in the row layout resource. |
| 92 | * These two parameters are typically parallel arrays. |
| 93 | * </p> |
| 94 | * <p> |
| 95 | * Android provides some standard row layout resources. These are in the |
| 96 | * {@link android.R.layout} class, and have names such as simple_list_item_1, |
| 97 | * simple_list_item_2, and two_line_list_item. The following layout XML is the |
| 98 | * source for the resource two_line_list_item, which displays two data |
| 99 | * fields,one above the other, for each list row. |
| 100 | * </p> |
| 101 | * |
| 102 | * <pre> |
| 103 | * <?xml version="1.0" encoding="utf-8"?> |
| 104 | * <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| 105 | * android:layout_width="match_parent" |
| 106 | * android:layout_height="wrap_content" |
| 107 | * android:orientation="vertical"> |
| 108 | * |
| 109 | * <TextView android:id="@+id/text1" |
| 110 | * android:textSize="16sp" |
| 111 | * android:textStyle="bold" |
| 112 | * android:layout_width="match_parent" |
| 113 | * android:layout_height="wrap_content"/> |
| 114 | * |
| 115 | * <TextView android:id="@+id/text2" |
| 116 | * android:textSize="16sp" |
| 117 | * android:layout_width="match_parent" |
| 118 | * android:layout_height="wrap_content"/> |
| 119 | * </LinearLayout> |
| 120 | * </pre> |
| 121 | * |
| 122 | * <p> |
| 123 | * You must identify the data bound to each TextView object in this layout. The |
| 124 | * syntax for this is discussed in the next section. |
| 125 | * </p> |
| 126 | * <p> |
| 127 | * <strong>Binding to Data</strong> |
| 128 | * </p> |
| 129 | * <p> |
| 130 | * You bind the ListFragment's ListView object to data using a class that |
| 131 | * implements the {@link android.widget.ListAdapter ListAdapter} interface. |
| 132 | * Android provides two standard list adapters: |
| 133 | * {@link android.widget.SimpleAdapter SimpleAdapter} for static data (Maps), |
| 134 | * and {@link android.widget.SimpleCursorAdapter SimpleCursorAdapter} for Cursor |
| 135 | * query results. |
| 136 | * </p> |
Dianne Hackborn | dd913a5 | 2010-07-22 12:17:04 -0700 | [diff] [blame] | 137 | * <p> |
| 138 | * You <b>must</b> use |
| 139 | * {@link #setListAdapter(ListAdapter) ListFragment.setListAdapter()} to |
| 140 | * associate the list with an adapter. Do not directly call |
| 141 | * {@link ListView#setAdapter(ListAdapter) ListView.setAdapter()} or else |
| 142 | * important initialization will be skipped. |
| 143 | * </p> |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 144 | * |
| 145 | * @see #setListAdapter |
| 146 | * @see android.widget.ListView |
| 147 | */ |
| 148 | public class ListFragment extends Fragment { |
| 149 | final private Handler mHandler = new Handler(); |
| 150 | |
| 151 | final private Runnable mRequestFocus = new Runnable() { |
| 152 | public void run() { |
| 153 | mList.focusableViewAvailable(mList); |
| 154 | } |
| 155 | }; |
| 156 | |
| 157 | final private AdapterView.OnItemClickListener mOnClickListener |
| 158 | = new AdapterView.OnItemClickListener() { |
| 159 | public void onItemClick(AdapterView<?> parent, View v, int position, long id) { |
| 160 | onListItemClick((ListView)parent, v, position, id); |
| 161 | } |
| 162 | }; |
| 163 | |
| 164 | ListAdapter mAdapter; |
| 165 | ListView mList; |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 166 | View mEmptyView; |
| 167 | TextView mStandardEmptyView; |
| 168 | View mProgressContainer; |
| 169 | View mListContainer; |
Dianne Hackborn | afc4b28 | 2011-06-10 17:03:42 -0700 | [diff] [blame^] | 170 | CharSequence mEmptyText; |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 171 | boolean mListShown; |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 172 | |
| 173 | public ListFragment() { |
| 174 | } |
| 175 | |
| 176 | /** |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 177 | * Provide default implementation to return a simple list view. Subclasses |
| 178 | * can override to replace with their own layout. If doing so, the |
| 179 | * returned view hierarchy <em>must</em> have a ListView whose id |
Dianne Hackborn | b0c56b2 | 2010-06-28 21:46:32 -0700 | [diff] [blame] | 180 | * is {@link android.R.id#list android.R.id.list} and can optionally |
| 181 | * have a sibling view id {@link android.R.id#empty android.R.id.empty} |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 182 | * that is to be shown when the list is empty. |
Dianne Hackborn | ef769f6 | 2010-07-12 11:40:53 -0700 | [diff] [blame] | 183 | * |
| 184 | * <p>If you are overriding this method with your own custom content, |
| 185 | * consider including the standard layout {@link android.R.layout#list_content} |
| 186 | * in your layout file, so that you continue to retain all of the standard |
| 187 | * behavior of ListFragment. In particular, this is currently the only |
| 188 | * way to have the built-in indeterminant progress state be shown. |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 189 | */ |
| 190 | @Override |
| 191 | public View onCreateView(LayoutInflater inflater, ViewGroup container, |
| 192 | Bundle savedInstanceState) { |
Dianne Hackborn | ef769f6 | 2010-07-12 11:40:53 -0700 | [diff] [blame] | 193 | return inflater.inflate(com.android.internal.R.layout.list_content, |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 194 | container, false); |
| 195 | } |
| 196 | |
| 197 | /** |
Dianne Hackborn | 16f6e89 | 2011-04-15 19:00:20 -0700 | [diff] [blame] | 198 | * Attach to list view once the view hierarchy has been created. |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 199 | */ |
| 200 | @Override |
Dianne Hackborn | 16f6e89 | 2011-04-15 19:00:20 -0700 | [diff] [blame] | 201 | public void onViewCreated(View view, Bundle savedInstanceState) { |
| 202 | super.onViewCreated(view, savedInstanceState); |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 203 | ensureList(); |
| 204 | } |
| 205 | |
| 206 | /** |
| 207 | * Detach from list view. |
| 208 | */ |
| 209 | @Override |
| 210 | public void onDestroyView() { |
| 211 | mHandler.removeCallbacks(mRequestFocus); |
| 212 | mList = null; |
Dianne Hackborn | afc4b28 | 2011-06-10 17:03:42 -0700 | [diff] [blame^] | 213 | mListShown = false; |
| 214 | mEmptyView = mProgressContainer = mListContainer = null; |
| 215 | mStandardEmptyView = null; |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 216 | super.onDestroyView(); |
| 217 | } |
| 218 | |
| 219 | /** |
| 220 | * This method will be called when an item in the list is selected. |
| 221 | * Subclasses should override. Subclasses can call |
| 222 | * getListView().getItemAtPosition(position) if they need to access the |
| 223 | * data associated with the selected item. |
| 224 | * |
| 225 | * @param l The ListView where the click happened |
| 226 | * @param v The view that was clicked within the ListView |
| 227 | * @param position The position of the view in the list |
| 228 | * @param id The row id of the item that was clicked |
| 229 | */ |
| 230 | public void onListItemClick(ListView l, View v, int position, long id) { |
| 231 | } |
| 232 | |
| 233 | /** |
| 234 | * Provide the cursor for the list view. |
| 235 | */ |
| 236 | public void setListAdapter(ListAdapter adapter) { |
Dianne Hackborn | ef769f6 | 2010-07-12 11:40:53 -0700 | [diff] [blame] | 237 | boolean hadAdapter = mAdapter != null; |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 238 | mAdapter = adapter; |
| 239 | if (mList != null) { |
| 240 | mList.setAdapter(adapter); |
Dianne Hackborn | ef769f6 | 2010-07-12 11:40:53 -0700 | [diff] [blame] | 241 | if (!mListShown && !hadAdapter) { |
| 242 | // The list was hidden, and previously didn't have an |
| 243 | // adapter. It is now time to show it. |
| 244 | setListShown(true, getView().getWindowToken() != null); |
| 245 | } |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 246 | } |
| 247 | } |
| 248 | |
| 249 | /** |
| 250 | * Set the currently selected list item to the specified |
| 251 | * position with the adapter's data |
| 252 | * |
| 253 | * @param position |
| 254 | */ |
| 255 | public void setSelection(int position) { |
| 256 | ensureList(); |
| 257 | mList.setSelection(position); |
| 258 | } |
| 259 | |
| 260 | /** |
| 261 | * Get the position of the currently selected list item. |
| 262 | */ |
| 263 | public int getSelectedItemPosition() { |
| 264 | ensureList(); |
| 265 | return mList.getSelectedItemPosition(); |
| 266 | } |
| 267 | |
| 268 | /** |
| 269 | * Get the cursor row ID of the currently selected list item. |
| 270 | */ |
| 271 | public long getSelectedItemId() { |
| 272 | ensureList(); |
| 273 | return mList.getSelectedItemId(); |
| 274 | } |
| 275 | |
| 276 | /** |
| 277 | * Get the activity's list view widget. |
| 278 | */ |
| 279 | public ListView getListView() { |
| 280 | ensureList(); |
| 281 | return mList; |
| 282 | } |
| 283 | |
| 284 | /** |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 285 | * The default content for a ListFragment has a TextView that can |
| 286 | * be shown when the list is empty. If you would like to have it |
| 287 | * shown, call this method to supply the text it should use. |
| 288 | */ |
| 289 | public void setEmptyText(CharSequence text) { |
| 290 | ensureList(); |
| 291 | if (mStandardEmptyView == null) { |
| 292 | throw new IllegalStateException("Can't be used with a custom content view"); |
| 293 | } |
Dianne Hackborn | dd913a5 | 2010-07-22 12:17:04 -0700 | [diff] [blame] | 294 | mStandardEmptyView.setText(text); |
Dianne Hackborn | afc4b28 | 2011-06-10 17:03:42 -0700 | [diff] [blame^] | 295 | if (mEmptyText == null) { |
Dianne Hackborn | dd913a5 | 2010-07-22 12:17:04 -0700 | [diff] [blame] | 296 | mList.setEmptyView(mStandardEmptyView); |
Dianne Hackborn | dd913a5 | 2010-07-22 12:17:04 -0700 | [diff] [blame] | 297 | } |
Dianne Hackborn | afc4b28 | 2011-06-10 17:03:42 -0700 | [diff] [blame^] | 298 | mEmptyText = text; |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 299 | } |
| 300 | |
| 301 | /** |
| 302 | * Control whether the list is being displayed. You can make it not |
| 303 | * displayed if you are waiting for the initial data to show in it. During |
| 304 | * this time an indeterminant progress indicator will be shown instead. |
| 305 | * |
Dianne Hackborn | ef769f6 | 2010-07-12 11:40:53 -0700 | [diff] [blame] | 306 | * <p>Applications do not normally need to use this themselves. The default |
| 307 | * behavior of ListFragment is to start with the list not being shown, only |
| 308 | * showing it once an adapter is given with {@link #setListAdapter(ListAdapter)}. |
| 309 | * If the list at that point had not been shown, when it does get shown |
| 310 | * it will be do without the user ever seeing the hidden state. |
| 311 | * |
| 312 | * @param shown If true, the list view is shown; if false, the progress |
| 313 | * indicator. The initial value is true. |
| 314 | */ |
| 315 | public void setListShown(boolean shown) { |
| 316 | setListShown(shown, true); |
| 317 | } |
| 318 | |
| 319 | /** |
| 320 | * Like {@link #setListShown(boolean)}, but no animation is used when |
| 321 | * transitioning from the previous state. |
| 322 | */ |
| 323 | public void setListShownNoAnimation(boolean shown) { |
| 324 | setListShown(shown, false); |
| 325 | } |
| 326 | |
| 327 | /** |
| 328 | * Control whether the list is being displayed. You can make it not |
| 329 | * displayed if you are waiting for the initial data to show in it. During |
| 330 | * this time an indeterminant progress indicator will be shown instead. |
| 331 | * |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 332 | * @param shown If true, the list view is shown; if false, the progress |
| 333 | * indicator. The initial value is true. |
| 334 | * @param animate If true, an animation will be used to transition to the |
| 335 | * new state. |
| 336 | */ |
Dianne Hackborn | ef769f6 | 2010-07-12 11:40:53 -0700 | [diff] [blame] | 337 | private void setListShown(boolean shown, boolean animate) { |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 338 | ensureList(); |
| 339 | if (mProgressContainer == null) { |
| 340 | throw new IllegalStateException("Can't be used with a custom content view"); |
| 341 | } |
| 342 | if (mListShown == shown) { |
| 343 | return; |
| 344 | } |
| 345 | mListShown = shown; |
| 346 | if (shown) { |
| 347 | if (animate) { |
| 348 | mProgressContainer.startAnimation(AnimationUtils.loadAnimation( |
| 349 | getActivity(), android.R.anim.fade_out)); |
| 350 | mListContainer.startAnimation(AnimationUtils.loadAnimation( |
| 351 | getActivity(), android.R.anim.fade_in)); |
Dianne Hackborn | afc4b28 | 2011-06-10 17:03:42 -0700 | [diff] [blame^] | 352 | } else { |
| 353 | mProgressContainer.clearAnimation(); |
| 354 | mListContainer.clearAnimation(); |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 355 | } |
| 356 | mProgressContainer.setVisibility(View.GONE); |
| 357 | mListContainer.setVisibility(View.VISIBLE); |
| 358 | } else { |
| 359 | if (animate) { |
| 360 | mProgressContainer.startAnimation(AnimationUtils.loadAnimation( |
| 361 | getActivity(), android.R.anim.fade_in)); |
| 362 | mListContainer.startAnimation(AnimationUtils.loadAnimation( |
| 363 | getActivity(), android.R.anim.fade_out)); |
Dianne Hackborn | afc4b28 | 2011-06-10 17:03:42 -0700 | [diff] [blame^] | 364 | } else { |
| 365 | mProgressContainer.clearAnimation(); |
| 366 | mListContainer.clearAnimation(); |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 367 | } |
| 368 | mProgressContainer.setVisibility(View.VISIBLE); |
| 369 | mListContainer.setVisibility(View.GONE); |
| 370 | } |
| 371 | } |
| 372 | |
| 373 | /** |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 374 | * Get the ListAdapter associated with this activity's ListView. |
| 375 | */ |
| 376 | public ListAdapter getListAdapter() { |
| 377 | return mAdapter; |
| 378 | } |
| 379 | |
| 380 | private void ensureList() { |
| 381 | if (mList != null) { |
| 382 | return; |
| 383 | } |
| 384 | View root = getView(); |
| 385 | if (root == null) { |
| 386 | throw new IllegalStateException("Content view not yet created"); |
| 387 | } |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 388 | if (root instanceof ListView) { |
| 389 | mList = (ListView)root; |
| 390 | } else { |
| 391 | mStandardEmptyView = (TextView)root.findViewById( |
| 392 | com.android.internal.R.id.internalEmpty); |
| 393 | if (mStandardEmptyView == null) { |
| 394 | mEmptyView = root.findViewById(android.R.id.empty); |
Dianne Hackborn | afc4b28 | 2011-06-10 17:03:42 -0700 | [diff] [blame^] | 395 | } else { |
| 396 | mStandardEmptyView.setVisibility(View.GONE); |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 397 | } |
| 398 | mProgressContainer = root.findViewById(com.android.internal.R.id.progressContainer); |
| 399 | mListContainer = root.findViewById(com.android.internal.R.id.listContainer); |
| 400 | View rawListView = root.findViewById(android.R.id.list); |
| 401 | if (!(rawListView instanceof ListView)) { |
| 402 | throw new RuntimeException( |
| 403 | "Content has view with id attribute 'android.R.id.list' " |
| 404 | + "that is not a ListView class"); |
| 405 | } |
| 406 | mList = (ListView)rawListView; |
| 407 | if (mList == null) { |
| 408 | throw new RuntimeException( |
| 409 | "Your content must have a ListView whose id attribute is " + |
| 410 | "'android.R.id.list'"); |
| 411 | } |
| 412 | if (mEmptyView != null) { |
| 413 | mList.setEmptyView(mEmptyView); |
Dianne Hackborn | afc4b28 | 2011-06-10 17:03:42 -0700 | [diff] [blame^] | 414 | } else if (mEmptyText != null) { |
| 415 | mStandardEmptyView.setText(mEmptyText); |
| 416 | mList.setEmptyView(mStandardEmptyView); |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 417 | } |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 418 | } |
Dianne Hackborn | 445646c | 2010-06-25 15:52:59 -0700 | [diff] [blame] | 419 | mListShown = true; |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 420 | mList.setOnItemClickListener(mOnClickListener); |
| 421 | if (mAdapter != null) { |
Dianne Hackborn | afc4b28 | 2011-06-10 17:03:42 -0700 | [diff] [blame^] | 422 | ListAdapter adapter = mAdapter; |
| 423 | mAdapter = null; |
| 424 | setListAdapter(adapter); |
Dianne Hackborn | ef769f6 | 2010-07-12 11:40:53 -0700 | [diff] [blame] | 425 | } else { |
| 426 | // We are starting without an adapter, so assume we won't |
| 427 | // have our data right away and start with the progress indicator. |
| 428 | if (mProgressContainer != null) { |
| 429 | setListShown(false, false); |
| 430 | } |
Dianne Hackborn | 5ddd127 | 2010-06-12 10:15:28 -0700 | [diff] [blame] | 431 | } |
| 432 | mHandler.post(mRequestFocus); |
| 433 | } |
| 434 | } |