TimeZoneResultAdapter.java revision 143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3
1b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan/*
2b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * Copyright (C) 2013 The Android Open Source Project
3b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan *
4b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * Licensed under the Apache License, Version 2.0 (the "License");
5b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * you may not use this file except in compliance with the License.
6b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * You may obtain a copy of the License at
7b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan *
8b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan *      http://www.apache.org/licenses/LICENSE-2.0
9b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan *
10b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * Unless required by applicable law or agreed to in writing, software
11b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * distributed under the License is distributed on an "AS IS" BASIS,
12b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * See the License for the specific language governing permissions and
14b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * limitations under the License.
15b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan */
16b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
17b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanpackage com.android.timezonepicker;
18b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
19b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.content.Context;
20b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.content.SharedPreferences;
21b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.text.TextUtils;
22b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.util.Log;
23b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.view.LayoutInflater;
24b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.view.View;
25b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.view.ViewGroup;
26b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chanimport android.widget.AdapterView;
27b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chanimport android.widget.AdapterView.OnItemClickListener;
28b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.widget.BaseAdapter;
29b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.widget.TextView;
30b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
31b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport com.android.timezonepicker.TimeZoneFilterTypeAdapter.OnSetFilterListener;
32b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport com.android.timezonepicker.TimeZonePickerView.OnTimeZoneSetListener;
33b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
34b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.ArrayList;
35143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chanimport java.util.LinkedHashSet;
36b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
37b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chanpublic class TimeZoneResultAdapter extends BaseAdapter implements OnItemClickListener,
38b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        OnSetFilterListener {
39b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private static final String TAG = "TimeZoneResultAdapter";
40b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private static final int VIEW_TAG_TIME_ZONE = R.id.time_zone;
41b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
42b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    /** SharedPref name and key for recent time zones */
43b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private static final String SHARED_PREFS_NAME = "com.android.calendar_preferences";
44b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private static final String KEY_RECENT_TIMEZONES = "preferences_recent_timezones";
45b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
46b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    /**
47b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     * The delimiter we use when serializing recent timezones to shared
48b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     * preferences
49b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     */
50b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private static final String RECENT_TIMEZONES_DELIMITER = ",";
51b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
52b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    /** The maximum number of recent timezones to save */
53b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private static final int MAX_RECENT_TIMEZONES = 3;
54b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
55b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    static class ViewHolder {
56b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        TextView timeZone;
57b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        TextView timeOffset;
58b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        TextView location;
59b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
60b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        static void setupViewHolder(View v) {
61b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            ViewHolder vh = new ViewHolder();
62b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            vh.timeZone = (TextView) v.findViewById(R.id.time_zone);
63b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            vh.timeOffset = (TextView) v.findViewById(R.id.time_offset);
64b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            vh.location = (TextView) v.findViewById(R.id.location);
65b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            v.setTag(vh);
66b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        }
67b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
68b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
69b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private Context mContext;
70b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private LayoutInflater mInflater;
71b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
72b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private OnTimeZoneSetListener mTimeZoneSetListener;
73b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private TimeZoneData mTimeZoneData;
74b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
75b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private int[] mFilteredTimeZoneIndices;
76b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    private int mFilteredTimeZoneLength = 0;
77b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
78b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    public TimeZoneResultAdapter(Context context, TimeZoneData tzd,
79b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            com.android.timezonepicker.TimeZonePickerView.OnTimeZoneSetListener l) {
80b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        super();
81b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
82b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        mContext = context;
83b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        mTimeZoneData = tzd;
84b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        mTimeZoneSetListener = l;
85b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
86b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
87b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
88b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        mFilteredTimeZoneIndices = new int[mTimeZoneData.size()];
89b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
90b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        onSetFilter(TimeZoneFilterTypeAdapter.FILTER_TYPE_NONE, null, 0);
91b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
92b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
93b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    // Implements OnSetFilterListener
94b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    @Override
95b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    public void onSetFilter(int filterType, String str, int time) {
96b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        Log.d(TAG, "onSetFilter: " + filterType + " [" + str + "] " + time);
97b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
98b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        mFilteredTimeZoneLength = 0;
99b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        int idx = 0;
100b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
101b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        switch (filterType) {
102b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            case TimeZoneFilterTypeAdapter.FILTER_TYPE_EMPTY:
103b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                break;
104b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            case TimeZoneFilterTypeAdapter.FILTER_TYPE_NONE:
105b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                // Show the default/current value first
106b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                int defaultTzIndex = mTimeZoneData.getDefaultTimeZoneIndex();
107b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                if (defaultTzIndex != -1) {
108b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    mFilteredTimeZoneIndices[mFilteredTimeZoneLength++] = defaultTzIndex;
109b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                }
110b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
111b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                // Show the recent selections
112b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                SharedPreferences prefs = mContext.getSharedPreferences(SHARED_PREFS_NAME,
113b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                        Context.MODE_PRIVATE);
114b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                String recentsString = prefs.getString(KEY_RECENT_TIMEZONES, null);
115b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                if (!TextUtils.isEmpty(recentsString)) {
116b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    String[] recents = recentsString.split(RECENT_TIMEZONES_DELIMITER);
117b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    for (int i = recents.length - 1; i >= 0; i--) {
118b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                        if (!TextUtils.isEmpty(recents[i])
119b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                                && !recents[i].equals(mTimeZoneData.mDefaultTimeZoneId)) {
120b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                            int index = mTimeZoneData.findIndexByTimeZoneIdSlow(recents[i]);
121b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                            if (index != -1) {
122b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                                mFilteredTimeZoneIndices[mFilteredTimeZoneLength++] = index;
123b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                            }
124b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                        }
125b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    }
126b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                }
127b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
128b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                break;
129b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            case TimeZoneFilterTypeAdapter.FILTER_TYPE_GMT:
130b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                ArrayList<Integer> indices = mTimeZoneData.getTimeZonesByOffset(time);
131b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                if (indices != null) {
132b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    for (Integer i : indices) {
133b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                        mFilteredTimeZoneIndices[mFilteredTimeZoneLength++] = i;
134b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    }
135b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                }
136b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                break;
137b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            case TimeZoneFilterTypeAdapter.FILTER_TYPE_TIME:
1380717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                // TODO make this faster
1390717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                long now = System.currentTimeMillis();
140b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                for (TimeZoneInfo tzi : mTimeZoneData.mTimeZones) {
1410717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                    int localHr = tzi.getLocalHr(now);
1420717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                    boolean match = localHr == time;
1430717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                    if (!match && !TimeZoneData.is24HourFormat) {
1440717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                        // PM + noon cases
145215ec1009ae3b52ed491fde7b2aa0a13dd4387beMichael Chan                        if ((time + 12 == localHr) || (time == 12 && localHr == 0)) {
1460717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                            match = true;
1470717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                        }
1480717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                    }
1490717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan                    if (match) {
150b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                        mFilteredTimeZoneIndices[mFilteredTimeZoneLength++] = idx;
151b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    }
152b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    idx++;
153b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                }
154b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                break;
155b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            case TimeZoneFilterTypeAdapter.FILTER_TYPE_COUNTRY:
156b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                ArrayList<Integer> tzIds = mTimeZoneData.mTimeZonesByCountry.get(str);
157b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                if (tzIds != null) {
158b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    for (Integer tzi : tzIds) {
159b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                        mFilteredTimeZoneIndices[mFilteredTimeZoneLength++] = tzi;
160b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    }
161b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                }
162b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                break;
163b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            case TimeZoneFilterTypeAdapter.FILTER_TYPE_STATE:
164b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                // TODO Filter by state
165b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                break;
166b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            default:
167b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                throw new IllegalArgumentException();
168b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        }
169b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        notifyDataSetChanged();
170b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
171b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
172b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    /**
173b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     * Saves the given timezone ID as a recent timezone under shared
174b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     * preferences. If there are already the maximum number of recent timezones
175b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     * saved, it will remove the oldest and append this one.
176b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     *
177b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     * @param id the ID of the timezone to save
178b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     * @see {@link #MAX_RECENT_TIMEZONES}
179b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan     */
180b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    public void saveRecentTimezone(String id) {
181b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        SharedPreferences prefs = mContext.getSharedPreferences(SHARED_PREFS_NAME,
182b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                Context.MODE_PRIVATE);
183b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        String recentsString = prefs.getString(KEY_RECENT_TIMEZONES, null);
184b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        if (recentsString == null) {
185b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            recentsString = id;
186b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        } else {
187143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan            // De-dup
188143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan            LinkedHashSet<String> recents = new LinkedHashSet<String>();
189143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan            for(String tzId : recentsString.split(RECENT_TIMEZONES_DELIMITER)) {
190143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan                if (!recents.contains(tzId) && !id.equals(tzId)) {
191143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan                    recents.add(tzId);
192b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                }
193b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            }
194b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
195b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            while (recents.size() >= MAX_RECENT_TIMEZONES) {
196b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                recents.remove(0);
197b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            }
198b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            recents.add(id);
199b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
200b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            StringBuilder builder = new StringBuilder();
201b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            boolean first = true;
202b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            for (String recent : recents) {
203b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                if (first) {
204b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    first = false;
205b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                } else {
206b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                    builder.append(RECENT_TIMEZONES_DELIMITER);
207b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                }
208b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan                builder.append(recent);
209b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            }
210b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            recentsString = builder.toString();
211b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        }
212b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
213b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        prefs.edit().putString(KEY_RECENT_TIMEZONES, recentsString).apply();
214b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
215b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
216b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    @Override
217b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    public int getCount() {
218b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        return mFilteredTimeZoneLength;
219b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
220b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
221b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    @Override
222215ec1009ae3b52ed491fde7b2aa0a13dd4387beMichael Chan    public Object getItem(int position) {
223b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        if (position < 0 || position >= mFilteredTimeZoneLength) {
224b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            return null;
225b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        }
226b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
227b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        return mTimeZoneData.get(mFilteredTimeZoneIndices[position]);
228b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
229b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
230b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    @Override
231b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chan    public boolean areAllItemsEnabled() {
232b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chan        return false;
233b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chan    }
234b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chan
235b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chan    @Override
236215ec1009ae3b52ed491fde7b2aa0a13dd4387beMichael Chan    public boolean isEnabled(int position) {
237215ec1009ae3b52ed491fde7b2aa0a13dd4387beMichael Chan        return mFilteredTimeZoneIndices[position] >= 0;
238215ec1009ae3b52ed491fde7b2aa0a13dd4387beMichael Chan    }
239215ec1009ae3b52ed491fde7b2aa0a13dd4387beMichael Chan
240215ec1009ae3b52ed491fde7b2aa0a13dd4387beMichael Chan    @Override
241b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    public long getItemId(int position) {
242b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        return mFilteredTimeZoneIndices[position];
243b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
244b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
245b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    @Override
246b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    public View getView(int position, View convertView, ViewGroup parent) {
247b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        View v = convertView;
248b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
249b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        if (v == null) {
250b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            v = mInflater.inflate(R.layout.time_zone_item, null);
251b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            ViewHolder.setupViewHolder(v);
252b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        }
253b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
254b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        ViewHolder vh = (ViewHolder) v.getTag();
255b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
256143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan        TimeZoneInfo tzi = mTimeZoneData.get(mFilteredTimeZoneIndices[position]);
257143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan        v.setTag(VIEW_TAG_TIME_ZONE, tzi);
258215ec1009ae3b52ed491fde7b2aa0a13dd4387beMichael Chan
259143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan        vh.timeZone.setText(tzi.mDisplayName);
260215ec1009ae3b52ed491fde7b2aa0a13dd4387beMichael Chan
261143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan        vh.timeOffset.setText(tzi.getGmtDisplayName(mContext));
262b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
263143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan        String location = tzi.mCountry;
264143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan        if (location == null) {
265143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan            vh.location.setVisibility(View.INVISIBLE);
266b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        } else {
267143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan            vh.location.setText(location);
268143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan            vh.location.setVisibility(View.VISIBLE);
269b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        }
270b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
271b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        return v;
272b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
273b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
274b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    @Override
275b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    public boolean hasStableIds() {
276b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        return true;
277b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
278b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan
279b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chan    // Implements OnItemClickListener
280b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    @Override
281b064db0d1a7ffcedddd691b35d57e2cdb0268883Michael Chan    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
282b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        if (mTimeZoneSetListener != null) {
283b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            TimeZoneInfo tzi = (TimeZoneInfo) v.getTag(VIEW_TAG_TIME_ZONE);
284b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            mTimeZoneSetListener.onTimeZoneSet(tzi);
285b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan            saveRecentTimezone(tzi.mTzId);
286b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan        }
287b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan    }
288b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan}
289