1 /* 2 * Copyright (C) 2010 Google Inc. 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.android.loaderapp.fragments; 18 19 import com.android.loaderapp.CursorFactoryListAdapter; 20 import com.android.loaderapp.R; 21 import com.android.loaderapp.CursorFactoryListAdapter.ResourceViewFactory; 22 import com.android.loaderapp.model.ContactsListLoader; 23 24 import android.app.LoaderManagingFragment; 25 import android.content.Loader; 26 import android.content.res.Configuration; 27 import android.database.Cursor; 28 import android.net.Uri; 29 import android.os.Bundle; 30 import android.provider.ContactsContract.Contacts; 31 import android.view.LayoutInflater; 32 import android.view.View; 33 import android.view.ViewGroup; 34 import android.widget.AdapterView; 35 import android.widget.ListView; 36 import android.widget.AdapterView.OnItemClickListener; 37 38 public class ContactsListFragment extends LoaderManagingFragment<Cursor> 39 implements OnItemClickListener { 40 private static final int LOADER_LIST = 1; 41 42 public static final int MODE_NULL = 0; 43 public static final int MODE_VISIBLE = 1; 44 public static final int MODE_STREQUENT = 2; 45 public static final int MODE_GROUP = 3; 46 47 private static final int DEFAULT_MODE = MODE_VISIBLE; 48 49 public interface Controller { onContactSelected(Uri contact)50 public void onContactSelected(Uri contact); 51 } 52 53 Controller mController; 54 ListView mList; 55 CursorFactoryListAdapter mAdapter; 56 int mMode; 57 String mGroupName; 58 ContactsListFragment()59 public ContactsListFragment() { 60 super(); 61 mMode = DEFAULT_MODE; 62 } 63 ContactsListFragment(int mode)64 public ContactsListFragment(int mode) { 65 super(); 66 mMode = mode; 67 } 68 69 @Override onInitializeLoaders()70 public void onInitializeLoaders() { 71 if (mMode != MODE_NULL) { 72 startLoading(LOADER_LIST, null); 73 } 74 } 75 76 @Override onCreateLoader(int id, Bundle args)77 protected Loader onCreateLoader(int id, Bundle args) { 78 switch (mMode) { 79 case MODE_GROUP: 80 return ContactsListLoader.newContactGroupLoader(getActivity(), mGroupName); 81 case MODE_STREQUENT: 82 return ContactsListLoader.newStrequentContactsLoader(getActivity()); 83 default: 84 return ContactsListLoader.newVisibleContactsLoader(getActivity()); 85 } 86 } 87 88 @Override onLoadFinished(Loader<Cursor> loader, Cursor data)89 public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 90 mAdapter.changeCursor(data); 91 } 92 93 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState)94 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { 95 ListView list = (ListView) inflater.inflate(R.layout.contacts_list, container, false); 96 list.setOnItemClickListener(this); 97 mAdapter = new CursorFactoryListAdapter(getActivity(), 98 new ResourceViewFactory(getListItemResId())); 99 list.setAdapter(mAdapter); 100 mList = list; 101 return list; 102 } 103 setMode(int mode)104 public void setMode(int mode) { 105 boolean reload = mode != mMode; 106 mMode = mode; 107 if (reload) { 108 startLoading(LOADER_LIST, null); 109 } 110 } 111 setGroupMode(String groupName)112 public void setGroupMode(String groupName) { 113 boolean reload = (MODE_GROUP != mMode) || !groupName.equals(mGroupName); 114 mMode = MODE_GROUP; 115 mGroupName = groupName; 116 if (reload) { 117 startLoading(LOADER_LIST, null); 118 } 119 } 120 setController(Controller controller)121 public void setController(Controller controller) { 122 mController = controller; 123 } 124 getMode()125 public int getMode() { 126 return mMode; 127 } 128 129 /** 130 * Build the {@link Contacts#CONTENT_LOOKUP_URI} for the given 131 * {@link ListView} position. 132 */ getContactUri(int position)133 public Uri getContactUri(int position) { 134 if (position == ListView.INVALID_POSITION) { 135 throw new IllegalArgumentException("Position not in list bounds"); 136 } 137 138 final Cursor cursor = (Cursor) mAdapter.getItem(position); 139 if (cursor == null) { 140 return null; 141 } 142 143 // Build and return soft, lookup reference 144 final long contactId = cursor.getLong(ContactsListLoader.COLUMN_ID); 145 final String lookupKey = cursor.getString(ContactsListLoader.COLUMN_LOOKUP_KEY); 146 return Contacts.getLookupUri(contactId, lookupKey); 147 } 148 onItemClick(AdapterView<?> parent, View view, int position, long id)149 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 150 // The user clicked on an item in the left side pane, start loading the data for it 151 if (mController != null) { 152 mController.onContactSelected(getContactUri(position)); 153 } 154 } 155 getListItemResId()156 private int getListItemResId() { 157 // This should be done using the resource system, but for now we want to override 158 // the configuration for running xlarge UIs on normal screens and vice versa 159 Configuration config = getActivity().getResources().getConfiguration(); 160 int screenLayoutSize = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK; 161 if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_XLARGE) { 162 return R.layout.xlarge_list_item; 163 } else { 164 return R.layout.normal_list_item; 165 } 166 } 167 } 168