1eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton/*
2eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton * Copyright (C) 2010 Google Inc.
3eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton *
4eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton * Licensed under the Apache License, Version 2.0 (the "License");
5eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton * you may not use this file except in compliance with the License.
6eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton * You may obtain a copy of the License at
7eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton *
8eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton *	    http://www.apache.org/licenses/LICENSE-2.0
9eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton *
10eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton * Unless required by applicable law or agreed to in writing, software
11eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton * distributed under the License is distributed on an "AS IS" BASIS,
12eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton * See the License for the specific language governing permissions and
14eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton * limitations under the License
15eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton */
16eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
17eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonpackage com.android.loaderapp.fragments;
18eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
199b694a3b8f0339356c304ae078f63ae91df42226Jeff Hamiltonimport com.android.loaderapp.CursorFactoryListAdapter;
20eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport com.android.loaderapp.R;
219b694a3b8f0339356c304ae078f63ae91df42226Jeff Hamiltonimport com.android.loaderapp.CursorFactoryListAdapter.ResourceViewFactory;
22eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport com.android.loaderapp.model.ContactsListLoader;
23eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
249b694a3b8f0339356c304ae078f63ae91df42226Jeff Hamiltonimport android.app.LoaderManagingFragment;
259b694a3b8f0339356c304ae078f63ae91df42226Jeff Hamiltonimport android.content.Loader;
26eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.content.res.Configuration;
27eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.database.Cursor;
28eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.net.Uri;
29eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.os.Bundle;
30eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.provider.ContactsContract.Contacts;
31eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.view.LayoutInflater;
32eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.view.View;
33eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.view.ViewGroup;
34eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.widget.AdapterView;
35eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.widget.ListView;
36eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonimport android.widget.AdapterView.OnItemClickListener;
37eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
38eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamiltonpublic class ContactsListFragment extends LoaderManagingFragment<Cursor>
39eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        implements OnItemClickListener {
40eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    private static final int LOADER_LIST = 1;
41eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
42eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public static final int MODE_NULL = 0;
43eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public static final int MODE_VISIBLE = 1;
44eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public static final int MODE_STREQUENT = 2;
45eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public static final int MODE_GROUP = 3;
46eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
47eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    private static final int DEFAULT_MODE = MODE_VISIBLE;
48eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
49eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public interface Controller {
50eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        public void onContactSelected(Uri contact);
51eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
52eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
53eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    Controller mController;
54eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    ListView mList;
55eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    CursorFactoryListAdapter mAdapter;
56eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    int mMode;
57eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    String mGroupName;
58eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
59eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public ContactsListFragment() {
60eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        super();
61eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        mMode = DEFAULT_MODE;
62eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
63eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
64eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public ContactsListFragment(int mode) {
65eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        super();
66eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        mMode = mode;
67eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
68eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
69eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    @Override
70eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public void onInitializeLoaders() {
71eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        if (mMode != MODE_NULL) {
72eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            startLoading(LOADER_LIST, null);
73eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        }
74eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
75eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
76eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    @Override
77eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    protected Loader onCreateLoader(int id, Bundle args) {
78eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        switch (mMode) {
79eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            case MODE_GROUP:
80eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton                return ContactsListLoader.newContactGroupLoader(getActivity(), mGroupName);
81eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            case MODE_STREQUENT:
82eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton                return ContactsListLoader.newStrequentContactsLoader(getActivity());
83eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            default:
84eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton                return ContactsListLoader.newVisibleContactsLoader(getActivity());
85eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        }
86eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
87eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
88eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    @Override
89eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
90eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        mAdapter.changeCursor(data);
91eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
92eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
93eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    @Override
94b8f21e4c3acceba68a69088e1c4dc489321737f2Jeff Hamilton    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
95eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        ListView list = (ListView) inflater.inflate(R.layout.contacts_list, container, false);
96eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        list.setOnItemClickListener(this);
97eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        mAdapter = new CursorFactoryListAdapter(getActivity(),
98eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton                new ResourceViewFactory(getListItemResId()));
99eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        list.setAdapter(mAdapter);
100eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        mList = list;
101eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        return list;
102eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
103eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
104eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public void setMode(int mode) {
105eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        boolean reload = mode != mMode;
106eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        mMode = mode;
107eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        if (reload) {
108eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            startLoading(LOADER_LIST, null);
109eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        }
110eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
111eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
112eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public void setGroupMode(String groupName) {
113eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        boolean reload = (MODE_GROUP != mMode) || !groupName.equals(mGroupName);
114eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        mMode = MODE_GROUP;
115eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        mGroupName = groupName;
116eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        if (reload) {
117eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            startLoading(LOADER_LIST, null);
118eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        }
119eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
1207a5e3bc28faed91ec17d1da9c82253a8679c1f4dJeff Hamilton
121eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public void setController(Controller controller) {
122eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        mController = controller;
123eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
124eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
1257a5e3bc28faed91ec17d1da9c82253a8679c1f4dJeff Hamilton    public int getMode() {
1267a5e3bc28faed91ec17d1da9c82253a8679c1f4dJeff Hamilton        return mMode;
1277a5e3bc28faed91ec17d1da9c82253a8679c1f4dJeff Hamilton    }
1287a5e3bc28faed91ec17d1da9c82253a8679c1f4dJeff Hamilton
129eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    /**
130eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton     * Build the {@link Contacts#CONTENT_LOOKUP_URI} for the given
131eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton     * {@link ListView} position.
132eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton     */
133eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public Uri getContactUri(int position) {
134eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        if (position == ListView.INVALID_POSITION) {
135eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            throw new IllegalArgumentException("Position not in list bounds");
136eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        }
137eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
138eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        final Cursor cursor = (Cursor) mAdapter.getItem(position);
139eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        if (cursor == null) {
140eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            return null;
141eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        }
142eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
143eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        // Build and return soft, lookup reference
144eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        final long contactId = cursor.getLong(ContactsListLoader.COLUMN_ID);
145eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        final String lookupKey = cursor.getString(ContactsListLoader.COLUMN_LOOKUP_KEY);
146eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        return Contacts.getLookupUri(contactId, lookupKey);
147eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
148eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
149eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
150eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        // The user clicked on an item in the left side pane, start loading the data for it
151eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        if (mController != null) {
152eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            mController.onContactSelected(getContactUri(position));
153eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        }
154eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
155eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton
156eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    private int getListItemResId() {
157eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        // This should be done using the resource system, but for now we want to override
158eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        // the configuration for running xlarge UIs on normal screens and vice versa
159eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        Configuration config = getActivity().getResources().getConfiguration();
160eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        int screenLayoutSize = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
161eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
162eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            return R.layout.xlarge_list_item;
163eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        } else {
164eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton            return R.layout.normal_list_item;
165eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton        }
166eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton    }
167eda61bd20eaf7b1f627bc44962709bf8f1b09628Jeff Hamilton}
168