SelectFromListWizardFragment.java revision 21e8c04b87d6cdf30547fed13a1f7ddf606438f9
165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.connectivity.setup; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Activity; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Fragment; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Fengimport android.content.res.Resources; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.wifi.ScanResult; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.net.wifi.WifiManager; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Handler; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Parcel; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Parcelable; 2921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Fengimport android.support.v17.leanback.widget.VerticalGridView; 3021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Fengimport android.support.v7.util.SortedList; 3121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Fengimport android.support.v7.widget.RecyclerView; 3221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Fengimport android.support.v7.widget.util.SortedListAdapterCallback; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.LayoutInflater; 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.View; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.ViewGroup; 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.inputmethod.InputMethodManager; 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.AdapterView; 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.FrameLayout; 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.ImageView; 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.TextView; 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 426316b89e65828d537da309851529d1295efd5730Tony Mantlerimport com.android.tv.settings.R; 436316b89e65828d537da309851529d1295efd5730Tony Mantlerimport com.android.tv.settings.connectivity.WifiSecurity; 446316b89e65828d537da309851529d1295efd5730Tony Mantlerimport com.android.tv.settings.util.AccessibilityHelper; 456316b89e65828d537da309851529d1295efd5730Tony Mantler 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.ArrayList; 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Comparator; 4821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Fengimport java.util.List; 4921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Fengimport java.util.TreeSet; 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Displays a UI for selecting a wifi network from a list in the "wizard" style. 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class SelectFromListWizardFragment extends Fragment { 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static class ListItemComparator implements Comparator<ListItem> { 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public int compare(ListItem o1, ListItem o2) { 5921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng int pinnedPos1 = o1.getPinnedPosition(); 6021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng int pinnedPos2 = o2.getPinnedPosition(); 6121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 6221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (pinnedPos1 != PinnedListItem.UNPINNED && pinnedPos2 == PinnedListItem.UNPINNED) { 6321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (pinnedPos1 == PinnedListItem.FIRST) return -1; 6421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (pinnedPos1 == PinnedListItem.LAST) return 1; 6521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 6621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 6721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (pinnedPos1 == PinnedListItem.UNPINNED && pinnedPos2 != PinnedListItem.UNPINNED) { 6821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (pinnedPos2 == PinnedListItem.FIRST) return 1; 6921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (pinnedPos2 == PinnedListItem.LAST) return -1; 7021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 7121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 7221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (pinnedPos1 != PinnedListItem.UNPINNED && pinnedPos2 != PinnedListItem.UNPINNED) { 7321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (pinnedPos1 == pinnedPos2) { 7421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng PinnedListItem po1 = (PinnedListItem) o1; 7521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng PinnedListItem po2 = (PinnedListItem) o2; 7621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return po1.getPinnedPriority() - po2.getPinnedPriority(); 7721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 7821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (pinnedPos1 == PinnedListItem.LAST) return 1; 7921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 8021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return -1; 8121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 8221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ScanResult o1ScanResult = o1.getScanResult(); 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ScanResult o2ScanResult = o2.getScanResult(); 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (o1ScanResult == null) { 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (o2ScanResult == null) { 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return 0; 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return 1; 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (o2ScanResult == null) { 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return -1; 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int levelDiff = o2ScanResult.level - o1ScanResult.level; 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (levelDiff != 0) { 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return levelDiff; 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return o1ScanResult.SSID.compareTo(o2ScanResult.SSID); 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static class ListItem implements Parcelable { 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final String mName; 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final int mIconResource; 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final int mIconLevel; 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final boolean mHasIconLevel; 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final ScanResult mScanResult; 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public ListItem(String name, int iconResource) { 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mName = name; 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mIconResource = iconResource; 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mIconLevel = 0; 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHasIconLevel = false; 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mScanResult = null; 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public ListItem(ScanResult scanResult) { 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mName = scanResult.SSID; 1237e552863cea67e57b375f3db15e0baf70e22c39eTony Mantler mIconResource = WifiSecurity.NONE == WifiSecurity.getSecurity(scanResult) 1247e552863cea67e57b375f3db15e0baf70e22c39eTony Mantler ? R.drawable.setup_wifi_signal_open 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane : R.drawable.setup_wifi_signal_lock; 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mIconLevel = WifiManager.calculateSignalLevel(scanResult.level, 4); 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHasIconLevel = true; 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mScanResult = scanResult; 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String getName() { 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mName; 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int getIconResource() { 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mIconResource; 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int getIconLevel() { 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mIconLevel; 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean hasIconLevel() { 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mHasIconLevel; 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ScanResult getScanResult() { 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mScanResult; 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng /** 15221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng * Returns whether this item is pinned to the front/back of a sorted list. Returns 15321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng * PinnedListItem.UNPINNED if the item is not pinned. 15421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng * @return the pinned/unpinned setting for this item. 15521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng */ 15621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public int getPinnedPosition() { 15721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return PinnedListItem.UNPINNED; 15821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 15921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public String toString() { 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mName; 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static Parcelable.Creator<ListItem> CREATOR = new Parcelable.Creator<ListItem>() { 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public ListItem createFromParcel(Parcel source) { 1697e552863cea67e57b375f3db15e0baf70e22c39eTony Mantler ScanResult scanResult = source.readParcelable(ScanResult.class.getClassLoader()); 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (scanResult == null) { 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return new ListItem(source.readString(), source.readInt()); 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return new ListItem(scanResult); 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public ListItem[] newArray(int size) { 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return new ListItem[size]; 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public int describeContents() { 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return 0; 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void writeToParcel(Parcel dest, int flags) { 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dest.writeParcelable(mScanResult, flags); 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mScanResult == null) { 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dest.writeString(mName); 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dest.writeInt(mIconResource); 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public boolean equals(Object o) { 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (o instanceof ListItem) { 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ListItem li = (ListItem) o; 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mScanResult == null && li.mScanResult == null) { 20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mName.equals(li.mName); 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return (mScanResult != null && li.mScanResult != null && mName.equals(li.mName) && 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane WifiSecurity.getSecurity(mScanResult) 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane == WifiSecurity.getSecurity(li.mScanResult)); 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public static class PinnedListItem extends ListItem { 21321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public static final int UNPINNED = 0; 21421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public static final int FIRST = 1; 21521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public static final int LAST = 2; 21621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 21721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private int mPinnedPosition; 21821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private int mPinnedPriority; 21921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 22021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public PinnedListItem( 22121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng String name, int iconResource, int pinnedPosition, int pinnedPriority) { 22221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng super(name, iconResource); 22321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mPinnedPosition = pinnedPosition; 22421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mPinnedPriority = pinnedPriority; 22521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 22621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 22721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng @Override 22821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public int getPinnedPosition() { 22921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return mPinnedPosition; 23021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 23121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 23221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng /** 23321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng * Returns the priority for this item, which is used for ordering the item between pinned 23421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng * items in a sorted list. For example, if two items are pinned to the front of the list 23521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng * (FIRST), the priority value is used to determine their ordering. 23621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng * @return the sorting priority for this item 23721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng */ 23821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public int getPinnedPriority() { 23921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return mPinnedPriority; 24021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 24121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 24221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public interface Listener { 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void onListSelectionComplete(ListItem listItem); 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void onListFocusChanged(ListItem listItem); 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 24821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private static interface ActionListener { 24921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void onClick(ListItem item); 25021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void onFocus(ListItem item); 25121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 25221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 25321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private static class ListItemViewHolder extends RecyclerView.ViewHolder { 25421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public ListItemViewHolder(View v) { 25521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng super(v); 25621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 25721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 25821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void init(ListItem item, View.OnClickListener onClick, 25921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng View.OnFocusChangeListener onFocusChange) { 26021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng TextView title = (TextView) itemView.findViewById(R.id.list_item_text); 26121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng title.setText(item.getName()); 26221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng itemView.setOnClickListener(onClick); 26321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng itemView.setOnFocusChangeListener(onFocusChange); 26421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 26521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng int iconResource = item.getIconResource(); 26621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ImageView icon = (ImageView) itemView.findViewById(R.id.list_item_icon); 26721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng // Set the icon if there is one. 26821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (iconResource == 0) { 26921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng icon.setVisibility(View.GONE); 27021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return; 27121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 27221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng icon.setVisibility(View.VISIBLE); 27321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng icon.setImageResource(iconResource); 27421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (item.hasIconLevel()) { 27521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng icon.setImageLevel(item.getIconLevel()); 27621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 27721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 27821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 27921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 28021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private class VerticalListAdapter extends RecyclerView.Adapter { 28121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private SortedList mItems; 28221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private final ActionListener mActionListener; 28321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 28421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public VerticalListAdapter(ActionListener actionListener, List<ListItem> choices) { 28521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng super(); 28621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mActionListener = actionListener; 28721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ListItemComparator comparator = new ListItemComparator(); 28821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mItems = new SortedList<ListItem>( 28921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ListItem.class, new SortedListAdapterCallback<ListItem>(this) { 29021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng @Override 29121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public int compare(ListItem t0, ListItem t1) { 29221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return comparator.compare(t0, t1); 29321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 29421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 29521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng @Override 29621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public boolean areContentsTheSame(ListItem oldItem, ListItem newItem) { 29721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return oldItem.equals(newItem); 29821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 29921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 30021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng @Override 30121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public boolean areItemsTheSame(ListItem item1, ListItem item2) { 30221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return item1.equals(item2); 30321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 30421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng }); 30521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mItems.addAll(choices.toArray(new ListItem[0]), false); 30621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 30721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 30821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private View.OnClickListener createClickListener(final ListItem item) { 30921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return new View.OnClickListener() { 31021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng @Override 31121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void onClick(View v) { 31221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (v == null || v.getWindowToken() == null || mActionListener == null) { 31321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return; 31421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 31521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mActionListener.onClick(item); 31621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 31721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng }; 31821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 31921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 32021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private View.OnFocusChangeListener createFocusListener(final ListItem item) { 32121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return new View.OnFocusChangeListener() { 32221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng @Override 32321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void onFocusChange(View v, boolean hasFocus) { 32421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (v == null || v.getWindowToken() == null || mActionListener == null 32521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng || !hasFocus) { 32621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return; 32721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 32821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mActionListener.onFocus(item); 32921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 33021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng }; 33121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 33221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 33321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng @Override 33421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 33521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService( 33621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng Context.LAYOUT_INFLATER_SERVICE); 33721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng View v = inflater.inflate(R.layout.setup_list_item, parent, false); 33821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return new ListItemViewHolder(v); 33921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 34021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 34121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng @Override 34221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void onBindViewHolder(RecyclerView.ViewHolder baseHolder, int position) { 34321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (position >= mItems.size()) { 34421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return; 34521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 34621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 34721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ListItemViewHolder viewHolder = (ListItemViewHolder) baseHolder; 34821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ListItem item = (ListItem) mItems.get(position); 34921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng viewHolder.init((ListItem) item, createClickListener(item), createFocusListener(item)); 35021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 35121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 35221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public SortedList<ListItem> getItems() { 35321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return mItems; 35421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 35521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 35621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng @Override 35721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public int getItemCount() { 35821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng return mItems.size(); 35921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 36021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 36121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void updateItems(List<ListItem> inputItems) { 36221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng TreeSet<ListItem> newItemSet = new TreeSet<ListItem>(new ListItemComparator()); 36321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng for (ListItem item: inputItems) { 36421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng newItemSet.add(item); 36521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 36621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ArrayList<ListItem> toRemove = new ArrayList<ListItem>(); 36721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng for (int j = 0 ; j < mItems.size(); j++) { 36821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ListItem oldItem = (ListItem) mItems.get(j); 36921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (!newItemSet.contains(oldItem)) { 37021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng toRemove.add(oldItem); 37121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 37221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 37321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng for (ListItem item: toRemove) { 37421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mItems.remove(item); 37521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 37621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mItems.addAll(inputItems.toArray(new ListItem[0]), true); 37721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 37821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 37921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_TITLE = "title"; 38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_DESCRIPTION = "description"; 38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_LIST_ELEMENTS = "list_elements"; 38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_LAST_SELECTION = "last_selection"; 38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static SelectFromListWizardFragment newInstance(String title, String description, 38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<ListItem> listElements, ListItem lastSelection) { 38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane SelectFromListWizardFragment fragment = new SelectFromListWizardFragment(); 38865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle args = new Bundle(); 38965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putString(EXTRA_TITLE, title); 39065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putString(EXTRA_DESCRIPTION, description); 39165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putParcelableArrayList(EXTRA_LIST_ELEMENTS, listElements); 39265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putParcelable(EXTRA_LAST_SELECTION, lastSelection); 39365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane fragment.setArguments(args); 39465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return fragment; 39565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 39765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Handler mHandler; 39865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private View mMainView; 39921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private VerticalGridView mListView; 40021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private String mLastSelectedName; 40121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 40221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng private void updateSelected(String lastSelectionName) { 40321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng SortedList<ListItem> items = ((VerticalListAdapter) mListView.getAdapter()).getItems(); 40421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng for (int i = 0; i < items.size(); i++) { 40521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ListItem item = (ListItem) items.get(i); 40621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (lastSelectionName.equals(item.getName())) { 40721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mListView.setSelectedPosition(i); 40821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng break; 40965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 41065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 41165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 41265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 41321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void update(List<ListItem> listElements) { 41421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng VerticalListAdapter adapter = (VerticalListAdapter) mListView.getAdapter(); 41521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng adapter.updateItems(listElements); 41621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng updateSelected(mLastSelectedName); 41721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 41821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 41965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 42065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) { 42121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng Resources resources = getContext().getResources(); 42221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 42365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler = new Handler(); 42465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mMainView = inflater.inflate(R.layout.account_content_area, container, false); 4256316b89e65828d537da309851529d1295efd5730Tony Mantler 4266316b89e65828d537da309851529d1295efd5730Tony Mantler final ViewGroup descriptionArea = (ViewGroup) mMainView.findViewById(R.id.description); 4276316b89e65828d537da309851529d1295efd5730Tony Mantler final View content = inflater.inflate(R.layout.wifi_content, descriptionArea, false); 4286316b89e65828d537da309851529d1295efd5730Tony Mantler descriptionArea.addView(content); 4296316b89e65828d537da309851529d1295efd5730Tony Mantler 4306316b89e65828d537da309851529d1295efd5730Tony Mantler final ViewGroup actionArea = (ViewGroup) mMainView.findViewById(R.id.action); 43165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 43265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TextView titleText = (TextView) content.findViewById(R.id.title_text); 43365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane TextView descriptionText = (TextView) content.findViewById(R.id.description_text); 43465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 43565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle args = getArguments(); 43665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = args.getString(EXTRA_TITLE); 43765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String description = args.getString(EXTRA_DESCRIPTION); 43865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 43965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean forceFocusable = AccessibilityHelper.forceFocusableViews(getActivity()); 44065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (title != null) { 44165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setText(title); 44265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setVisibility(View.VISIBLE); 44365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (forceFocusable) { 44465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setFocusable(true); 44565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setFocusableInTouchMode(true); 44665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 44765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 44865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane titleText.setVisibility(View.GONE); 44965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 45165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (description != null) { 45265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane descriptionText.setText(description); 45365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane descriptionText.setVisibility(View.VISIBLE); 45465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (forceFocusable) { 45565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane descriptionText.setFocusable(true); 45665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane descriptionText.setFocusableInTouchMode(true); 45765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 45865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 45965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane descriptionText.setVisibility(View.GONE); 46065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 46165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ArrayList<ListItem> listItems = args.getParcelableArrayList(EXTRA_LIST_ELEMENTS); 46365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 46421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mListView = 46521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng (VerticalGridView) inflater.inflate(R.layout.setup_list_view, actionArea, false); 46621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mListView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE); 46721e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mListView.setWindowAlignmentOffsetPercent( 46821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng resources.getFloat(R.dimen.setup_scroll_list_window_offset_percent)); 46921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng 47021e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng actionArea.addView(mListView); 47121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ActionListener actionListener = new ActionListener() { 47265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 47321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void onClick(ListItem item) { 47465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Activity a = getActivity(); 47548fce31d5176b2f4100da514dd46a45f24e41c84Tony Mantler if (a instanceof Listener && isResumed()) { 47621e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ((Listener) a).onListSelectionComplete(item); 47765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 47965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 48065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 48121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng public void onFocus(ListItem item) { 48265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Activity a = getActivity(); 48321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mLastSelectedName = item.getName(); 48465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (a instanceof Listener) { 48521e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ((Listener) a).onListFocusChanged(item); 48665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 48821e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng }; 48921e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng mListView.setAdapter(new VerticalListAdapter(actionListener, listItems)); 49065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 49121e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng ListItem lastSelection = args.getParcelable(EXTRA_LAST_SELECTION); 49221e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng if (lastSelection != null) { 49321e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng updateSelected(lastSelection.getName()); 49421e8c04b87d6cdf30547fed13a1f7ddf606438f9Powei Feng } 49565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mMainView; 49665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 49765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 49865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 49965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onResume() { 50065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onResume(); 50165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mHandler.post(new Runnable() { 50265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 50365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void run() { 50465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane InputMethodManager inputMethodManager = (InputMethodManager) getActivity() 50565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .getSystemService(Context.INPUT_METHOD_SERVICE); 50665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane inputMethodManager.hideSoftInputFromWindow( 50765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mMainView.getApplicationWindowToken(), 0); 50865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 50965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }); 51065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 51165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 512