ListFragment.java revision ef769f6e4849d5d2580570ce08f9493dd43e7f0d
15ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn/* 25ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Copyright (C) 2010 The Android Open Source Project 35ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 45ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 55ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * you may not use this file except in compliance with the License. 65ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * You may obtain a copy of the License at 75ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 85ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 95ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 105ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 115ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 125ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * See the License for the specific language governing permissions and 145ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * limitations under the License. 155ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 165ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 175ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornpackage android.app; 185ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 195ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornimport android.os.Bundle; 205ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornimport android.os.Handler; 215ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornimport android.view.LayoutInflater; 225ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornimport android.view.View; 235ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornimport android.view.ViewGroup; 24445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackbornimport android.view.animation.AnimationUtils; 255ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornimport android.widget.AdapterView; 265ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornimport android.widget.ListAdapter; 275ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornimport android.widget.ListView; 28445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackbornimport android.widget.TextView; 295ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 305ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn/** 315ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * An fragment that displays a list of items by binding to a data source such as 325ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * an array or Cursor, and exposes event handlers when the user selects an item. 335ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 345ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * ListActivity hosts a {@link android.widget.ListView ListView} object that can 355ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * be bound to different data sources, typically either an array or a Cursor 365ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * holding query results. Binding, screen layout, and row layout are discussed 375ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * in the following sections. 385ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 395ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <strong>Screen Layout</strong> 405ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </p> 415ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 425ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * ListActivity has a default layout that consists of a single list view. 435ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * However, if you desire, you can customize the fragment layout by returning 445ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * your own view hierarchy from {@link #onCreateView}. 455ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * To do this, your view hierarchy MUST contain a ListView object with the 465ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * id "@android:id/list" (or {@link android.R.id#list} if it's in code) 475ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 485ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Optionally, your view hierarchy can contain another view object of any type to 495ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * display when the list view is empty. This "empty list" notifier must have an 505ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * id "android:empty". Note that when an empty view is present, the list view 515ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * will be hidden when there is no data to display. 525ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 535ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * The following code demonstrates an (ugly) custom lisy layout. It has a list 545ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * with a green background, and an alternate red "no data" message. 555ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </p> 565ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 575ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <pre> 585ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <?xml version="1.0" encoding="utf-8"?> 595ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 605ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:orientation="vertical" 615ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_width="match_parent" 625ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_height="match_parent" 635ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:paddingLeft="8dp" 645ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:paddingRight="8dp"> 655ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 665ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <ListView android:id="@id/android:list" 675ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_width="match_parent" 685ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_height="match_parent" 695ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:background="#00FF00" 705ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_weight="1" 715ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:drawSelectorOnTop="false"/> 725ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 735ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <TextView android:id="@id/android:empty" 745ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_width="match_parent" 755ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_height="match_parent" 765ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:background="#FF0000" 775ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:text="No data"/> 785ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </LinearLayout> 795ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </pre> 805ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 815ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 825ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <strong>Row Layout</strong> 835ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </p> 845ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 855ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * You can specify the layout of individual rows in the list. You do this by 865ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * specifying a layout resource in the ListAdapter object hosted by the fragment 875ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * (the ListAdapter binds the ListView to the data; more on this later). 885ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 895ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * A ListAdapter constructor takes a parameter that specifies a layout resource 905ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * for each row. It also has two additional parameters that let you specify 915ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * which data field to associate with which object in the row layout resource. 925ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * These two parameters are typically parallel arrays. 935ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </p> 945ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 955ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Android provides some standard row layout resources. These are in the 965ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * {@link android.R.layout} class, and have names such as simple_list_item_1, 975ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * simple_list_item_2, and two_line_list_item. The following layout XML is the 985ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * source for the resource two_line_list_item, which displays two data 995ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * fields,one above the other, for each list row. 1005ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </p> 1015ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 1025ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <pre> 1035ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <?xml version="1.0" encoding="utf-8"?> 1045ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 1055ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_width="match_parent" 1065ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_height="wrap_content" 1075ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:orientation="vertical"> 1085ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 1095ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <TextView android:id="@+id/text1" 1105ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:textSize="16sp" 1115ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:textStyle="bold" 1125ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_width="match_parent" 1135ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_height="wrap_content"/> 1145ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 1155ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <TextView android:id="@+id/text2" 1165ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:textSize="16sp" 1175ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_width="match_parent" 1185ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * android:layout_height="wrap_content"/> 1195ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </LinearLayout> 1205ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </pre> 1215ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 1225ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 1235ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * You must identify the data bound to each TextView object in this layout. The 1245ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * syntax for this is discussed in the next section. 1255ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </p> 1265ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 1275ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <strong>Binding to Data</strong> 1285ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </p> 1295ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * <p> 1305ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * You bind the ListFragment's ListView object to data using a class that 1315ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * implements the {@link android.widget.ListAdapter ListAdapter} interface. 1325ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Android provides two standard list adapters: 1335ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * {@link android.widget.SimpleAdapter SimpleAdapter} for static data (Maps), 1345ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * and {@link android.widget.SimpleCursorAdapter SimpleCursorAdapter} for Cursor 1355ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * query results. 1365ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * </p> 1375ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 1385ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * @see #setListAdapter 1395ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * @see android.widget.ListView 1405ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 1415ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackbornpublic class ListFragment extends Fragment { 1425ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn final private Handler mHandler = new Handler(); 1435ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 1445ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn final private Runnable mRequestFocus = new Runnable() { 1455ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public void run() { 1465ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn mList.focusableViewAvailable(mList); 1475ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 1485ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn }; 1495ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 1505ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn final private AdapterView.OnItemClickListener mOnClickListener 1515ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn = new AdapterView.OnItemClickListener() { 1525ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 1535ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn onListItemClick((ListView)parent, v, position, id); 1545ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 1555ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn }; 1565ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 1575ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn ListAdapter mAdapter; 1585ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn ListView mList; 159445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn View mEmptyView; 160445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn TextView mStandardEmptyView; 161445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn View mProgressContainer; 162445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn View mListContainer; 163445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn boolean mListShown; 1645ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 1655ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public ListFragment() { 1665ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 1675ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 1685ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 169445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * Provide default implementation to return a simple list view. Subclasses 170445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * can override to replace with their own layout. If doing so, the 171445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * returned view hierarchy <em>must</em> have a ListView whose id 172b0c56b24aada23461c04746926ba185dfdbb8b5bDianne Hackborn * is {@link android.R.id#list android.R.id.list} and can optionally 173b0c56b24aada23461c04746926ba185dfdbb8b5bDianne Hackborn * have a sibling view id {@link android.R.id#empty android.R.id.empty} 174445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * that is to be shown when the list is empty. 175ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * 176ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * <p>If you are overriding this method with your own custom content, 177ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * consider including the standard layout {@link android.R.layout#list_content} 178ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * in your layout file, so that you continue to retain all of the standard 179ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * behavior of ListFragment. In particular, this is currently the only 180ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * way to have the built-in indeterminant progress state be shown. 1815ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 1825ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn @Override 1835ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public View onCreateView(LayoutInflater inflater, ViewGroup container, 1845ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn Bundle savedInstanceState) { 185ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn return inflater.inflate(com.android.internal.R.layout.list_content, 1865ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn container, false); 1875ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 1885ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 1895ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 1905ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Attach to list view once Fragment is ready to run. 1915ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 1925ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn @Override 193c801768e4d29667a2608695449ebc2833ba0f200Dianne Hackborn public void onActivityCreated(Bundle savedInstanceState) { 194c801768e4d29667a2608695449ebc2833ba0f200Dianne Hackborn super.onActivityCreated(savedInstanceState); 1955ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn ensureList(); 1965ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 1975ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 1985ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 1995ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Detach from list view. 2005ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 2015ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn @Override 2025ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public void onDestroyView() { 2035ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn mHandler.removeCallbacks(mRequestFocus); 2045ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn mList = null; 2055ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn super.onDestroyView(); 2065ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 2075ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 2085ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 2095ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * This method will be called when an item in the list is selected. 2105ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Subclasses should override. Subclasses can call 2115ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * getListView().getItemAtPosition(position) if they need to access the 2125ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * data associated with the selected item. 2135ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 2145ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * @param l The ListView where the click happened 2155ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * @param v The view that was clicked within the ListView 2165ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * @param position The position of the view in the list 2175ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * @param id The row id of the item that was clicked 2185ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 2195ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public void onListItemClick(ListView l, View v, int position, long id) { 2205ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 2215ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 2225ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 2235ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Provide the cursor for the list view. 2245ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 2255ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public void setListAdapter(ListAdapter adapter) { 226ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn boolean hadAdapter = mAdapter != null; 2275ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn mAdapter = adapter; 2285ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn if (mList != null) { 2295ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn mList.setAdapter(adapter); 230ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn if (!mListShown && !hadAdapter) { 231ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn // The list was hidden, and previously didn't have an 232ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn // adapter. It is now time to show it. 233ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn setListShown(true, getView().getWindowToken() != null); 234ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn } 2355ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 2365ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 2375ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 2385ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 2395ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Set the currently selected list item to the specified 2405ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * position with the adapter's data 2415ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * 2425ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * @param position 2435ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 2445ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public void setSelection(int position) { 2455ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn ensureList(); 2465ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn mList.setSelection(position); 2475ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 2485ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 2495ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 2505ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Get the position of the currently selected list item. 2515ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 2525ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public int getSelectedItemPosition() { 2535ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn ensureList(); 2545ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn return mList.getSelectedItemPosition(); 2555ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 2565ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 2575ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 2585ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Get the cursor row ID of the currently selected list item. 2595ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 2605ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public long getSelectedItemId() { 2615ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn ensureList(); 2625ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn return mList.getSelectedItemId(); 2635ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 2645ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 2655ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 2665ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Get the activity's list view widget. 2675ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 2685ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public ListView getListView() { 2695ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn ensureList(); 2705ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn return mList; 2715ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 2725ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 2735ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn /** 274445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * The default content for a ListFragment has a TextView that can 275445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * be shown when the list is empty. If you would like to have it 276445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * shown, call this method to supply the text it should use. 277445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn */ 278445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn public void setEmptyText(CharSequence text) { 279445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn ensureList(); 280445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (mStandardEmptyView == null) { 281445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn throw new IllegalStateException("Can't be used with a custom content view"); 282445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 283c801768e4d29667a2608695449ebc2833ba0f200Dianne Hackborn mList.setEmptyView(mStandardEmptyView); 284445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 285445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn 286445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn /** 287445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * Control whether the list is being displayed. You can make it not 288445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * displayed if you are waiting for the initial data to show in it. During 289445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * this time an indeterminant progress indicator will be shown instead. 290445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * 291ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * <p>Applications do not normally need to use this themselves. The default 292ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * behavior of ListFragment is to start with the list not being shown, only 293ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * showing it once an adapter is given with {@link #setListAdapter(ListAdapter)}. 294ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * If the list at that point had not been shown, when it does get shown 295ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * it will be do without the user ever seeing the hidden state. 296ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * 297ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * @param shown If true, the list view is shown; if false, the progress 298ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * indicator. The initial value is true. 299ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn */ 300ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn public void setListShown(boolean shown) { 301ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn setListShown(shown, true); 302ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn } 303ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn 304ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn /** 305ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * Like {@link #setListShown(boolean)}, but no animation is used when 306ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * transitioning from the previous state. 307ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn */ 308ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn public void setListShownNoAnimation(boolean shown) { 309ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn setListShown(shown, false); 310ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn } 311ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn 312ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn /** 313ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * Control whether the list is being displayed. You can make it not 314ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * displayed if you are waiting for the initial data to show in it. During 315ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * this time an indeterminant progress indicator will be shown instead. 316ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn * 317445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * @param shown If true, the list view is shown; if false, the progress 318445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * indicator. The initial value is true. 319445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * @param animate If true, an animation will be used to transition to the 320445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn * new state. 321445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn */ 322ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn private void setListShown(boolean shown, boolean animate) { 323445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn ensureList(); 324445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (mProgressContainer == null) { 325445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn throw new IllegalStateException("Can't be used with a custom content view"); 326445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 327445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (mListShown == shown) { 328445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn return; 329445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 330445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mListShown = shown; 331445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (shown) { 332445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (animate) { 333445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mProgressContainer.startAnimation(AnimationUtils.loadAnimation( 334445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn getActivity(), android.R.anim.fade_out)); 335445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mListContainer.startAnimation(AnimationUtils.loadAnimation( 336445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn getActivity(), android.R.anim.fade_in)); 337445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 338445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mProgressContainer.setVisibility(View.GONE); 339445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mListContainer.setVisibility(View.VISIBLE); 340445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } else { 341445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (animate) { 342445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mProgressContainer.startAnimation(AnimationUtils.loadAnimation( 343445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn getActivity(), android.R.anim.fade_in)); 344445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mListContainer.startAnimation(AnimationUtils.loadAnimation( 345445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn getActivity(), android.R.anim.fade_out)); 346445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 347445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mProgressContainer.setVisibility(View.VISIBLE); 348445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mListContainer.setVisibility(View.GONE); 349445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 350445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 351445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn 352445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn /** 3535ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn * Get the ListAdapter associated with this activity's ListView. 3545ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn */ 3555ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn public ListAdapter getListAdapter() { 3565ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn return mAdapter; 3575ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 3585ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn 3595ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn private void ensureList() { 3605ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn if (mList != null) { 3615ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn return; 3625ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 3635ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn View root = getView(); 3645ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn if (root == null) { 3655ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn throw new IllegalStateException("Content view not yet created"); 3665ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 367445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (root instanceof ListView) { 368445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mList = (ListView)root; 369445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } else { 370445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mStandardEmptyView = (TextView)root.findViewById( 371445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn com.android.internal.R.id.internalEmpty); 372445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (mStandardEmptyView == null) { 373445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mEmptyView = root.findViewById(android.R.id.empty); 374445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 375445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mProgressContainer = root.findViewById(com.android.internal.R.id.progressContainer); 376445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mListContainer = root.findViewById(com.android.internal.R.id.listContainer); 377445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn View rawListView = root.findViewById(android.R.id.list); 378445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (!(rawListView instanceof ListView)) { 379445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn throw new RuntimeException( 380445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn "Content has view with id attribute 'android.R.id.list' " 381445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn + "that is not a ListView class"); 382445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 383445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mList = (ListView)rawListView; 384445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (mList == null) { 385445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn throw new RuntimeException( 386445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn "Your content must have a ListView whose id attribute is " + 387445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn "'android.R.id.list'"); 388445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 389445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn if (mEmptyView != null) { 390445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mList.setEmptyView(mEmptyView); 391445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn } 3925ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 393445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn mListShown = true; 3945ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn mList.setOnItemClickListener(mOnClickListener); 3955ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn if (mAdapter != null) { 3965ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn setListAdapter(mAdapter); 397ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn } else { 398ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn // We are starting without an adapter, so assume we won't 399ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn // have our data right away and start with the progress indicator. 400ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn if (mProgressContainer != null) { 401ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn setListShown(false, false); 402ef769f6e4849d5d2580570ce08f9493dd43e7f0dDianne Hackborn } 4035ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 4045ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn mHandler.post(mRequestFocus); 4055ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn } 4065ddd127d5a38d80c0d8087d1770f41f61f84f048Dianne Hackborn} 407