Use Spinner instead of Tabs, so that a 4th entry doesn't disappear off the screen.

This is for the 3 to 4 lists that you can switch between in the Settings->Apps
screen.

Bug: 6375122

Change-Id: I8a4e46b8aa3e06bc79edb5f65400462060fe5a29
This commit is contained in:
Amith Yamasani
2012-05-03 12:46:53 -07:00
parent 7dabe4583c
commit 7a3221bb95
4 changed files with 177 additions and 93 deletions

View File

@@ -2,7 +2,7 @@
<!-- <!--
/* /*
** **
** Copyright 2011, The Android Open Source Project ** Copyright 2012, The Android Open Source Project
** **
** Licensed under the Apache License, Version 2.0 (the "License"); ** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License. ** you may not use this file except in compliance with the License.
@@ -17,26 +17,11 @@
** limitations under the License. ** limitations under the License.
*/ */
--> -->
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
<TabHost android:id="@android:id/text1"
xmlns:android="http://schemas.android.com/apk/res/android" style="?android:attr/spinnerDropDownItemStyle"
android:id="@android:id/tabhost" android:textAppearance="?android:attr/textAppearanceMedium"
android:singleLine="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:ellipsize="marquee" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<include layout="@layout/tab_widget"/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
</TabHost>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2012, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
android:textAppearance="?android:attr/textAppearanceMedium"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee" />

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2012, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="48sp"
android:minWidth="180dp"
android:layout_marginLeft="@*android:dimen/preference_fragment_padding_side"
android:layout_marginRight="@*android:dimen/preference_fragment_padding_side"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@*android:dimen/preference_fragment_padding_side"
android:layout_marginRight="@*android:dimen/preference_fragment_padding_side"
android:scaleType="fitXY"
android:src="?android:attr/listDivider" />
<FrameLayout
android:id="@+id/spinner_content"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>

View File

@@ -36,6 +36,7 @@ import android.preference.PreferenceActivity;
import android.provider.Settings; import android.provider.Settings;
import android.text.format.Formatter; import android.text.format.Formatter;
import android.util.Log; import android.util.Log;
import android.util.SparseIntArray;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@@ -47,11 +48,13 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView; import android.widget.AbsListView;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.Filter; import android.widget.Filter;
import android.widget.Filterable; import android.widget.Filterable;
import android.widget.FrameLayout;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TabHost; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import com.android.internal.app.IMediaContainerService; import com.android.internal.app.IMediaContainerService;
@@ -113,8 +116,7 @@ final class CanBeOnSdCardChecker {
* intent. * intent.
*/ */
public class ManageApplications extends Fragment implements public class ManageApplications extends Fragment implements
OnItemClickListener, OnItemClickListener {
TabHost.TabContentFactory, TabHost.OnTabChangeListener {
static final String TAG = "ManageApplications"; static final String TAG = "ManageApplications";
static final boolean DEBUG = false; static final boolean DEBUG = false;
@@ -122,7 +124,7 @@ public class ManageApplications extends Fragment implements
private static final String EXTRA_FILTER_APPS = "filterApps"; private static final String EXTRA_FILTER_APPS = "filterApps";
private static final String EXTRA_SORT_ORDER = "sortOrder"; private static final String EXTRA_SORT_ORDER = "sortOrder";
private static final String EXTRA_SHOW_BACKGROUND = "showBackground"; private static final String EXTRA_SHOW_BACKGROUND = "showBackground";
private static final String EXTRA_DEFAULT_TAB_TAG = "defaultTabTag"; private static final String EXTRA_DEFAULT_LIST_TYPE = "defaultListType";
// attributes used as keys when passing values to InstalledAppDetails activity // attributes used as keys when passing values to InstalledAppDetails activity
public static final String APP_CHG = "chg"; public static final String APP_CHG = "chg";
@@ -178,8 +180,8 @@ public class ManageApplications extends Fragment implements
TextView mFreeStorageText; TextView mFreeStorageText;
private Menu mOptionsMenu; private Menu mOptionsMenu;
// These are for keeping track of activity and tab switch state. // These are for keeping track of activity and spinner switch state.
private int mCurView; private int mCurView;
private boolean mCreatedRunning; private boolean mCreatedRunning;
@@ -189,20 +191,19 @@ public class ManageApplications extends Fragment implements
private boolean mLastShowedInternalStorage = true; private boolean mLastShowedInternalStorage = true;
private long mLastUsedStorage, mLastAppStorage, mLastFreeStorage; private long mLastUsedStorage, mLastAppStorage, mLastFreeStorage;
static final String TAB_DOWNLOADED = "Downloaded"; static final int LIST_TYPE_DOWNLOADED = 0;
static final String TAB_RUNNING = "Running"; static final int LIST_TYPE_RUNNING = 1;
static final String TAB_ALL = "All"; static final int LIST_TYPE_SDCARD = 2;
static final String TAB_SDCARD = "OnSdCard"; static final int LIST_TYPE_ALL = 3;
private View mRootView; private View mRootView;
private boolean mShowBackground = false; private boolean mShowBackground = false;
// -------------- Copied from TabActivity -------------- private int mDefaultListType = -1;
private SparseIntArray mIndexToType = new SparseIntArray(4);
private TabHost mTabHost; private Spinner mSpinner;
private String mDefaultTab = null; private FrameLayout mSpinnerContent;
// -------------- Copied from TabActivity --------------
final Runnable mRunningProcessesAvail = new Runnable() { final Runnable mRunningProcessesAvail = new Runnable() {
public void run() { public void run() {
@@ -210,6 +211,14 @@ public class ManageApplications extends Fragment implements
} }
}; };
static class AppFilterAdapter extends ArrayAdapter<String> {
public AppFilterAdapter(Context context) {
super(context, R.layout.apps_spinner_item);
setDropDownViewResource(R.layout.apps_spinner_dropdown_item);
}
}
/* /*
* Custom adapter implementation for the ListView * Custom adapter implementation for the ListView
* This adapter maintains a map for each displayed application and its properties * This adapter maintains a map for each displayed application and its properties
@@ -509,7 +518,7 @@ public class ManageApplications extends Fragment implements
mApplicationsAdapter = new ApplicationsAdapter(mApplicationsState); mApplicationsAdapter = new ApplicationsAdapter(mApplicationsState);
Intent intent = getActivity().getIntent(); Intent intent = getActivity().getIntent();
String action = intent.getAction(); String action = intent.getAction();
String defaultTabTag = TAB_DOWNLOADED; int defaultListType = LIST_TYPE_DOWNLOADED;
String className = getArguments() != null String className = getArguments() != null
? getArguments().getString("classname") : null; ? getArguments().getString("classname") : null;
if (className == null) { if (className == null) {
@@ -517,27 +526,27 @@ public class ManageApplications extends Fragment implements
} }
if (className.equals(RunningServicesActivity.class.getName()) if (className.equals(RunningServicesActivity.class.getName())
|| className.endsWith(".RunningServices")) { || className.endsWith(".RunningServices")) {
defaultTabTag = TAB_RUNNING; defaultListType = LIST_TYPE_RUNNING;
} else if (className.equals(StorageUseActivity.class.getName()) } else if (className.equals(StorageUseActivity.class.getName())
|| Intent.ACTION_MANAGE_PACKAGE_STORAGE.equals(action) || Intent.ACTION_MANAGE_PACKAGE_STORAGE.equals(action)
|| className.endsWith(".StorageUse")) { || className.endsWith(".StorageUse")) {
mSortOrder = SORT_ORDER_SIZE; mSortOrder = SORT_ORDER_SIZE;
mFilterApps = FILTER_APPS_ALL; mFilterApps = FILTER_APPS_ALL;
defaultTabTag = TAB_ALL; defaultListType = LIST_TYPE_ALL;
} else if (Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS.equals(action)) { } else if (Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS.equals(action)) {
// Select the all-apps tab, with the default sorting // Select the all-apps list, with the default sorting
defaultTabTag = TAB_ALL; defaultListType = LIST_TYPE_ALL;
} }
if (savedInstanceState != null) { if (savedInstanceState != null) {
mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder); mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder);
mFilterApps = savedInstanceState.getInt(EXTRA_FILTER_APPS, mFilterApps); mFilterApps = savedInstanceState.getInt(EXTRA_FILTER_APPS, mFilterApps);
String tmp = savedInstanceState.getString(EXTRA_DEFAULT_TAB_TAG); int tmp = savedInstanceState.getInt(EXTRA_DEFAULT_LIST_TYPE, -1);
if (tmp != null) defaultTabTag = tmp; if (tmp != -1) defaultListType = tmp;
mShowBackground = savedInstanceState.getBoolean(EXTRA_SHOW_BACKGROUND, false); mShowBackground = savedInstanceState.getBoolean(EXTRA_SHOW_BACKGROUND, false);
} }
mDefaultTab = defaultTabTag; mDefaultListType = defaultListType;
final Intent containerIntent = new Intent().setComponent( final Intent containerIntent = new Intent().setComponent(
StorageMeasurement.DEFAULT_CONTAINER_COMPONENT); StorageMeasurement.DEFAULT_CONTAINER_COMPONENT);
@@ -579,34 +588,44 @@ public class ManageApplications extends Fragment implements
mCreatedRunning = mResumedRunning = false; mCreatedRunning = mResumedRunning = false;
mCurView = VIEW_NOTHING; mCurView = VIEW_NOTHING;
mTabHost = (TabHost) mInflater.inflate(R.layout.manage_apps_tab_content, container, false); View spinnerHost = mInflater.inflate(R.layout.manage_apps_spinner_content,
mTabHost.setup(); container, false);
final TabHost tabHost = mTabHost;
tabHost.addTab(tabHost.newTabSpec(TAB_DOWNLOADED) mSpinner = (Spinner) spinnerHost.findViewById(R.id.spinner);
.setIndicator(getActivity().getString(R.string.filter_apps_third_party), mSpinnerContent = (FrameLayout) spinnerHost.findViewById(R.id.spinner_content);
getActivity().getResources().getDrawable(R.drawable.ic_tab_download)) mSpinnerContent.addView(mRootView);
.setContent(this));
AppFilterAdapter sa = new AppFilterAdapter(getActivity());
mIndexToType.append(sa.getCount(), LIST_TYPE_DOWNLOADED);
sa.add(getActivity().getString(R.string.filter_apps_third_party));
if (!Environment.isExternalStorageEmulated()) { if (!Environment.isExternalStorageEmulated()) {
tabHost.addTab(tabHost.newTabSpec(TAB_SDCARD) mIndexToType.append(sa.getCount(), LIST_TYPE_SDCARD);
.setIndicator(getActivity().getString(R.string.filter_apps_onsdcard), sa.add(getActivity().getString(R.string.filter_apps_onsdcard));
getActivity().getResources().getDrawable(R.drawable.ic_tab_sdcard))
.setContent(this));
} }
tabHost.addTab(tabHost.newTabSpec(TAB_RUNNING) mIndexToType.append(sa.getCount(), LIST_TYPE_RUNNING);
.setIndicator(getActivity().getString(R.string.filter_apps_running), sa.add(getActivity().getString(R.string.filter_apps_running));
getActivity().getResources().getDrawable(R.drawable.ic_tab_running)) mIndexToType.append(sa.getCount(), LIST_TYPE_ALL);
.setContent(this)); sa.add(getActivity().getString(R.string.filter_apps_all));
tabHost.addTab(tabHost.newTabSpec(TAB_ALL)
.setIndicator(getActivity().getString(R.string.filter_apps_all),
getActivity().getResources().getDrawable(R.drawable.ic_tab_all))
.setContent(this));
tabHost.setCurrentTabByTag(mDefaultTab);
tabHost.setOnTabChangedListener(this);
// adjust padding around tabwidget as needed mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
prepareCustomPreferencesList(container, mTabHost, mListView, false); @Override
public void onItemSelected(AdapterView<?> parent,
View view, int position, long id) {
showCurrentList();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Nothing
}
return mTabHost; });
mSpinner.setSelection(getIndex(mDefaultListType));
mSpinner.setAdapter(sa);
prepareCustomPreferencesList(container, spinnerHost, mListView, false);
return spinnerHost;
} }
@Override @Override
@@ -618,9 +637,10 @@ public class ManageApplications extends Fragment implements
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
mActivityResumed = true; mActivityResumed = true;
showCurrentTab(); showCurrentList();
updateOptionsMenu(); updateOptionsMenu();
mTabHost.getTabWidget().setEnabled(true); mSpinner.setEnabled(true);
mSpinnerContent.setEnabled(true);
} }
@Override @Override
@@ -628,8 +648,8 @@ public class ManageApplications extends Fragment implements
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putInt(EXTRA_SORT_ORDER, mSortOrder); outState.putInt(EXTRA_SORT_ORDER, mSortOrder);
outState.putInt(EXTRA_FILTER_APPS, mFilterApps); outState.putInt(EXTRA_FILTER_APPS, mFilterApps);
if (mDefaultTab != null) { if (mDefaultListType != -1) {
outState.putString(EXTRA_DEFAULT_TAB_TAG, mDefaultTab); outState.putInt(EXTRA_DEFAULT_LIST_TYPE, mDefaultListType);
} }
outState.putBoolean(EXTRA_SHOW_BACKGROUND, mShowBackground); outState.putBoolean(EXTRA_SHOW_BACKGROUND, mShowBackground);
} }
@@ -643,7 +663,8 @@ public class ManageApplications extends Fragment implements
mRunningProcessesView.doPause(); mRunningProcessesView.doPause();
mResumedRunning = false; mResumedRunning = false;
} }
mTabHost.getTabWidget().setEnabled(false); mSpinner.setEnabled(false);
mSpinnerContent.setEnabled(false);
} }
@Override @Override
@@ -652,7 +673,14 @@ public class ManageApplications extends Fragment implements
mApplicationsState.requestSize(mCurrentPkgName); mApplicationsState.requestSize(mCurrentPkgName);
} }
} }
private int getIndex(int listType) {
for (int i = 0; i < mIndexToType.size(); i++) {
if (listType == mIndexToType.get(i)) return i;
}
return 0;
}
// utility method used to start sub activity // utility method used to start sub activity
private void startApplicationDetailsActivity() { private void startApplicationDetailsActivity() {
// start new fragment to display extended information // start new fragment to display extended information
@@ -751,10 +779,6 @@ public class ManageApplications extends Fragment implements
mCurrentPkgName = entry.info.packageName; mCurrentPkgName = entry.info.packageName;
startApplicationDetailsActivity(); startApplicationDetailsActivity();
} }
public View createTabContent(String tag) {
return mRootView;
}
static final int VIEW_NOTHING = 0; static final int VIEW_NOTHING = 0;
static final int VIEW_LIST = 1; static final int VIEW_LIST = 1;
@@ -910,16 +934,17 @@ public class ManageApplications extends Fragment implements
} }
} }
public void showCurrentTab() { public void showCurrentList() {
String tabId = mDefaultTab = mTabHost.getCurrentTabTag(); int listType = mIndexToType.get(mSpinner.getSelectedItemPosition());
int newOption; int newOption;
if (TAB_DOWNLOADED.equalsIgnoreCase(tabId)) { if (LIST_TYPE_DOWNLOADED == listType) {
newOption = FILTER_APPS_THIRD_PARTY; newOption = FILTER_APPS_THIRD_PARTY;
} else if (TAB_ALL.equalsIgnoreCase(tabId)) { } else if (LIST_TYPE_ALL == listType) {
newOption = FILTER_APPS_ALL; newOption = FILTER_APPS_ALL;
} else if (TAB_SDCARD.equalsIgnoreCase(tabId)) { } else if (LIST_TYPE_SDCARD == listType) {
newOption = FILTER_APPS_SDCARD; newOption = FILTER_APPS_SDCARD;
} else if (TAB_RUNNING.equalsIgnoreCase(tabId)) { } else if (LIST_TYPE_RUNNING == listType) {
((InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)) ((InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow( .hideSoftInputFromWindow(
getActivity().getWindow().getDecorView().getWindowToken(), 0); getActivity().getWindow().getDecorView().getWindowToken(), 0);
@@ -929,17 +954,13 @@ public class ManageApplications extends Fragment implements
// Invalid option. Do nothing // Invalid option. Do nothing
return; return;
} }
mFilterApps = newOption; mFilterApps = newOption;
selectView(VIEW_LIST); selectView(VIEW_LIST);
updateStorageUsage(); updateStorageUsage();
updateOptionsMenu(); updateOptionsMenu();
} }
public void onTabChanged(String tabId) {
showCurrentTab();
}
private volatile IMediaContainerService mContainerService; private volatile IMediaContainerService mContainerService;
private final ServiceConnection mContainerConnection = new ServiceConnection() { private final ServiceConnection mContainerConnection = new ServiceConnection() {