Dianne Hackborn | 9fd3b6e | 2011-02-01 10:38:02 -0800 | [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 com.example.android.apis.app; |
| 18 | |
| 19 | import android.support.v4.app.FragmentActivity; |
| 20 | import android.support.v4.app.FragmentManager; |
| 21 | import android.support.v4.app.ListFragment; |
| 22 | import android.support.v4.app.LoaderManager; |
| 23 | import android.support.v4.content.CursorLoader; |
| 24 | import android.support.v4.content.Loader; |
| 25 | import android.support.v4.widget.SimpleCursorAdapter; |
| 26 | |
| 27 | import android.database.Cursor; |
| 28 | import android.net.Uri; |
| 29 | import android.os.Bundle; |
| 30 | import android.provider.ContactsContract.Contacts; |
| 31 | import android.text.TextUtils; |
| 32 | import android.util.Log; |
| 33 | import android.view.Menu; |
| 34 | import android.view.MenuInflater; |
| 35 | import android.view.MenuItem; |
| 36 | import android.view.View; |
| 37 | import android.widget.ListView; |
| 38 | |
| 39 | /** |
| 40 | * Demonstration of more complex use if a ListFragment, including showing |
| 41 | * an empty view and loading progress. |
| 42 | */ |
| 43 | public class FragmentListCursorLoaderSupport extends FragmentActivity { |
| 44 | |
| 45 | @Override |
| 46 | protected void onCreate(Bundle savedInstanceState) { |
| 47 | super.onCreate(savedInstanceState); |
| 48 | |
| 49 | FragmentManager fm = getSupportFragmentManager(); |
| 50 | |
| 51 | // Create the list fragment and add it as our sole content. |
| 52 | if (fm.findFragmentById(android.R.id.content) == null) { |
| 53 | CursorLoaderListFragment list = new CursorLoaderListFragment(); |
| 54 | fm.beginTransaction().add(android.R.id.content, list).commit(); |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | //BEGIN_INCLUDE(fragment_cursor) |
| 59 | public static class CursorLoaderListFragment extends ListFragment |
| 60 | implements LoaderManager.LoaderCallbacks<Cursor> { |
| 61 | |
| 62 | // This is the Adapter being used to display the list's data. |
| 63 | SimpleCursorAdapter mAdapter; |
| 64 | |
| 65 | // If non-null, this is the current filter the user has provided. |
| 66 | String mCurFilter; |
| 67 | |
| 68 | @Override public void onActivityCreated(Bundle savedInstanceState) { |
| 69 | super.onActivityCreated(savedInstanceState); |
| 70 | |
| 71 | // Give some text to display if there is no data. In a real |
| 72 | // application this would come from a resource. |
| 73 | setEmptyText("No phone numbers"); |
| 74 | |
| 75 | // We have a menu item to show in action bar. |
| 76 | setHasOptionsMenu(true); |
| 77 | |
| 78 | // Create an empty adapter we will use to display the loaded data. |
| 79 | mAdapter = new SimpleCursorAdapter(getActivity(), |
| 80 | android.R.layout.simple_list_item_2, null, |
| 81 | new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS }, |
| 82 | new int[] { android.R.id.text1, android.R.id.text2 }, 0); |
| 83 | setListAdapter(mAdapter); |
| 84 | |
| 85 | // Prepare the loader. Either re-connect with an existing one, |
| 86 | // or start a new one. |
| 87 | getLoaderManager().initLoader(0, null, this); |
| 88 | } |
| 89 | |
| 90 | @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { |
| 91 | // Place an action bar item for searching. |
| 92 | //MenuItem item = menu.add("Search"); |
| 93 | //item.setIcon(android.R.drawable.ic_menu_search); |
| 94 | //item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); |
| 95 | //SearchView sv = new SearchView(getActivity()); |
| 96 | //sv.setOnQueryTextListener(this); |
| 97 | //item.setActionView(sv); |
| 98 | } |
| 99 | |
| 100 | public boolean onQueryTextChange(String newText) { |
| 101 | // Called when the action bar search text has changed. Update |
| 102 | // the search filter, and restart the loader to do a new query |
| 103 | // with this filter. |
| 104 | mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; |
| 105 | getLoaderManager().restartLoader(0, null, this); |
| 106 | return true; |
| 107 | } |
| 108 | |
| 109 | @Override public void onListItemClick(ListView l, View v, int position, long id) { |
| 110 | // Insert desired behavior here. |
| 111 | Log.i("FragmentComplexList", "Item clicked: " + id); |
| 112 | } |
| 113 | |
| 114 | // These are the Contacts rows that we will retrieve. |
| 115 | static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { |
| 116 | Contacts._ID, |
| 117 | Contacts.DISPLAY_NAME, |
| 118 | Contacts.CONTACT_STATUS, |
| 119 | Contacts.CONTACT_PRESENCE, |
| 120 | Contacts.PHOTO_ID, |
| 121 | Contacts.LOOKUP_KEY, |
| 122 | }; |
| 123 | |
| 124 | public Loader<Cursor> onCreateLoader(int id, Bundle args) { |
| 125 | // This is called when a new Loader needs to be created. This |
| 126 | // sample only has one Loader, so we don't care about the ID. |
| 127 | // First, pick the base URI to use depending on whether we are |
| 128 | // currently filtering. |
| 129 | Uri baseUri; |
| 130 | if (mCurFilter != null) { |
| 131 | baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, |
| 132 | Uri.encode(mCurFilter)); |
| 133 | } else { |
| 134 | baseUri = Contacts.CONTENT_URI; |
| 135 | } |
| 136 | |
| 137 | // Now create and return a CursorLoader that will take care of |
| 138 | // creating a Cursor for the data being displayed. |
| 139 | String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" |
| 140 | + Contacts.HAS_PHONE_NUMBER + "=1) AND (" |
| 141 | + Contacts.DISPLAY_NAME + " != '' ))"; |
| 142 | return new CursorLoader(getActivity(), baseUri, |
| 143 | CONTACTS_SUMMARY_PROJECTION, select, null, |
| 144 | Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); |
| 145 | } |
| 146 | |
| 147 | public void onLoadFinished(Loader<Cursor> loader, Cursor data) { |
| 148 | // Swap the new cursor in. (The framework will take care of closing the |
| 149 | // old cursor once we return.) |
| 150 | mAdapter.swapCursor(data); |
| 151 | } |
| 152 | |
| 153 | public void onLoaderReset(Loader<Cursor> loader) { |
| 154 | // This is called when the last Cursor provided to onLoadFinished() |
| 155 | // above is about to be closed. We need to make sure we are no |
| 156 | // longer using it. |
| 157 | mAdapter.swapCursor(null); |
| 158 | } |
| 159 | } |
| 160 | //END_INCLUDE(fragment_cursor) |
| 161 | } |