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