Replace battery usage breakdown list from tabs to dropdown list.
screen records: https://drive.google.com/file/d/15VJGQ_G2KIpyFcvZsyE0iRno0WZhfjGb/view?usp=sharing&resourcekey=0-bg48BsC2b-BT_80CGlzpWg https://drive.google.com/file/d/1RaoysytQ5oZQu8CNPhYgxqBahk3UfVbr/view?usp=sharing&resourcekey=0-Xk2J36fjYWBo6KpFTrMr4Q Bug: 264338267 Fix: 264338267 Test: manual Change-Id: Ic020cce711b5232adfc80272836d7c2d0250d94a
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
<!--
|
||||||
~ Copyright (C) 2022 The Android Open Source Project
|
~ Copyright (C) 2023 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.
|
||||||
@@ -15,23 +14,11 @@
|
|||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<LinearLayout
|
<Spinner
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:theme="@style/Theme.TabTheme"
|
android:id="@+id/spinner"
|
||||||
android:id="@+id/tab_container"
|
android:layout_width="wrap_content"
|
||||||
android:clipToPadding="true"
|
|
||||||
android:clipChildren="true"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:layout_marginStart="24dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
<com.google.android.material.tabs.TabLayout
|
android:theme="@style/Widget.PopupWindow.Settings" />
|
||||||
android:id="@+id/tabs"
|
|
||||||
style="@style/SettingsLibTabsStyle" />
|
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
|
||||||
android:id="@+id/view_pager"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@@ -5175,13 +5175,13 @@
|
|||||||
<!-- [CHAR_LIMIT=NONE] Accessibility content description for hourly battery chart view. -->
|
<!-- [CHAR_LIMIT=NONE] Accessibility content description for hourly battery chart view. -->
|
||||||
<string name="hourly_battery_usage_chart">Hourly battery usage chart</string>
|
<string name="hourly_battery_usage_chart">Hourly battery usage chart</string>
|
||||||
<!-- [CHAR_LIMIT=NONE] Battery usage breakdown title since last full charge -->
|
<!-- [CHAR_LIMIT=NONE] Battery usage breakdown title since last full charge -->
|
||||||
<string name="battery_usage_breakdown_title_since_last_full_charge">Usage proportional breakdown since last full charge</string>
|
<string name="battery_usage_breakdown_title_since_last_full_charge">Battery usage since last full charge</string>
|
||||||
<!-- [CHAR_LIMIT=NONE] Battery usage breakdown title for a selected slot -->
|
<!-- [CHAR_LIMIT=NONE] Battery usage breakdown title for a selected slot -->
|
||||||
<string name="battery_usage_breakdown_title_for_slot">Usage proportional breakdown for <xliff:g id="slot">%s</xliff:g></string>
|
<string name="battery_usage_breakdown_title_for_slot">Battery usage for <xliff:g id="slot">%s</xliff:g></string>
|
||||||
<!-- [CHAR_LIMIT=NONE] The tab title in the battery usage breakdown. -->
|
<!-- [CHAR_LIMIT=NONE] The spinner item text in the battery usage breakdown. -->
|
||||||
<string name="battery_usage_app_tab">App</string>
|
<string name="battery_usage_spinner_breakdown_by_apps">Breakdown by apps</string>
|
||||||
<!-- [CHAR_LIMIT=NONE] The tab title in the battery usage breakdown. -->
|
<!-- [CHAR_LIMIT=NONE] The spinner item text in the battery usage breakdown. -->
|
||||||
<string name="battery_usage_system_tab">System</string>
|
<string name="battery_usage_spinner_breakdown_by_system">Breakdown by system</string>
|
||||||
<!-- Process Stats strings -->
|
<!-- Process Stats strings -->
|
||||||
<skip />
|
<skip />
|
||||||
|
|
||||||
|
@@ -32,8 +32,8 @@
|
|||||||
"com.android.settings.fuelgauge.batteryusage.BatteryUsageBreakdownController"
|
"com.android.settings.fuelgauge.batteryusage.BatteryUsageBreakdownController"
|
||||||
settings:isPreferenceVisible="false">
|
settings:isPreferenceVisible="false">
|
||||||
|
|
||||||
<com.android.settings.fuelgauge.batteryusage.TabPreference
|
<com.android.settings.fuelgauge.batteryusage.SpinnerPreference
|
||||||
android:key="battery_usage_tab"
|
android:key="battery_usage_spinner"
|
||||||
settings:isPreferenceVisible="false" />
|
settings:isPreferenceVisible="false" />
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
@@ -24,12 +24,13 @@ import android.os.Looper;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceCategory;
|
import androidx.preference.PreferenceCategory;
|
||||||
import androidx.preference.PreferenceGroup;
|
import androidx.preference.PreferenceGroup;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
import androidx.viewpager2.widget.ViewPager2;
|
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -55,7 +56,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
|||||||
private static final String TAG = "BatteryUsageBreakdownController";
|
private static final String TAG = "BatteryUsageBreakdownController";
|
||||||
private static final String ROOT_PREFERENCE_KEY = "battery_usage_breakdown";
|
private static final String ROOT_PREFERENCE_KEY = "battery_usage_breakdown";
|
||||||
private static final String FOOTER_PREFERENCE_KEY = "battery_usage_footer";
|
private static final String FOOTER_PREFERENCE_KEY = "battery_usage_footer";
|
||||||
private static final String TAB_PREFERENCE_KEY = "battery_usage_tab";
|
private static final String SPINNER_PREFERENCE_KEY = "battery_usage_spinner";
|
||||||
private static final String APP_LIST_PREFERENCE_KEY = "app_list";
|
private static final String APP_LIST_PREFERENCE_KEY = "app_list";
|
||||||
private static final String PACKAGE_NAME_NONE = "none";
|
private static final String PACKAGE_NAME_NONE = "none";
|
||||||
private static final int ENABLED_ICON_ALPHA = 255;
|
private static final int ENABLED_ICON_ALPHA = 255;
|
||||||
@@ -69,7 +70,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final Map<String, Preference> mPreferenceCache = new HashMap<>();
|
final Map<String, Preference> mPreferenceCache = new HashMap<>();
|
||||||
|
|
||||||
private int mTabPosition;
|
private int mSpinnerPosition;
|
||||||
private String mSlotTimestamp;
|
private String mSlotTimestamp;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -77,7 +78,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
PreferenceCategory mRootPreference;
|
PreferenceCategory mRootPreference;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
TabPreference mTabPreference;
|
SpinnerPreference mSpinnerPreference;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
PreferenceGroup mAppListPreferenceGroup;
|
PreferenceGroup mAppListPreferenceGroup;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -145,26 +146,33 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
|||||||
super.displayPreference(screen);
|
super.displayPreference(screen);
|
||||||
mPrefContext = screen.getContext();
|
mPrefContext = screen.getContext();
|
||||||
mRootPreference = screen.findPreference(ROOT_PREFERENCE_KEY);
|
mRootPreference = screen.findPreference(ROOT_PREFERENCE_KEY);
|
||||||
mTabPreference = screen.findPreference(TAB_PREFERENCE_KEY);
|
mSpinnerPreference = screen.findPreference(SPINNER_PREFERENCE_KEY);
|
||||||
mAppListPreferenceGroup = screen.findPreference(APP_LIST_PREFERENCE_KEY);
|
mAppListPreferenceGroup = screen.findPreference(APP_LIST_PREFERENCE_KEY);
|
||||||
mFooterPreference = screen.findPreference(FOOTER_PREFERENCE_KEY);
|
mFooterPreference = screen.findPreference(FOOTER_PREFERENCE_KEY);
|
||||||
|
|
||||||
mAppListPreferenceGroup.setOrderingAsAdded(false);
|
mAppListPreferenceGroup.setOrderingAsAdded(false);
|
||||||
mTabPreference.initializeTabs(mFragment, new String[]{
|
mSpinnerPreference.initializeSpinner(
|
||||||
mPrefContext.getString(R.string.battery_usage_app_tab),
|
new String[]{
|
||||||
mPrefContext.getString(R.string.battery_usage_system_tab)
|
mPrefContext.getString(R.string.battery_usage_spinner_breakdown_by_apps),
|
||||||
});
|
mPrefContext.getString(R.string.battery_usage_spinner_breakdown_by_system)
|
||||||
mTabPreference.setOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
|
},
|
||||||
@Override
|
new AdapterView.OnItemSelectedListener() {
|
||||||
public void onPageSelected(int position) {
|
@Override
|
||||||
super.onPageSelected(position);
|
public void onItemSelected(
|
||||||
mTabPosition = position;
|
AdapterView<?> parent, View view, int position, long id) {
|
||||||
mHandler.post(() -> {
|
if (mSpinnerPosition != position) {
|
||||||
removeAndCacheAllPreferences();
|
mSpinnerPosition = position;
|
||||||
addAllPreferences();
|
mHandler.post(() -> {
|
||||||
|
removeAndCacheAllPreferences();
|
||||||
|
addAllPreferences();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -182,7 +190,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
|||||||
mSlotTimestamp = slotTimestamp;
|
mSlotTimestamp = slotTimestamp;
|
||||||
|
|
||||||
showCategoryTitle(slotTimestamp);
|
showCategoryTitle(slotTimestamp);
|
||||||
showTabAndAppList();
|
showSpinnerAndAppList();
|
||||||
showFooterPreference(isAllUsageDataEmpty);
|
showFooterPreference(isAllUsageDataEmpty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,12 +212,12 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
|||||||
mFooterPreference.setVisible(true);
|
mFooterPreference.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showTabAndAppList() {
|
private void showSpinnerAndAppList() {
|
||||||
removeAndCacheAllPreferences();
|
removeAndCacheAllPreferences();
|
||||||
if (mBatteryDiffData == null) {
|
if (mBatteryDiffData == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mTabPreference.setVisible(true);
|
mSpinnerPreference.setVisible(true);
|
||||||
mAppListPreferenceGroup.setVisible(true);
|
mAppListPreferenceGroup.setVisible(true);
|
||||||
mHandler.post(() -> {
|
mHandler.post(() -> {
|
||||||
addAllPreferences();
|
addAllPreferences();
|
||||||
@@ -222,7 +230,7 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
final List<BatteryDiffEntry> entries = mTabPosition == 0
|
final List<BatteryDiffEntry> entries = mSpinnerPosition == 0
|
||||||
? mBatteryDiffData.getAppDiffEntryList()
|
? mBatteryDiffData.getAppDiffEntryList()
|
||||||
: mBatteryDiffData.getSystemDiffEntryList();
|
: mBatteryDiffData.getSystemDiffEntryList();
|
||||||
int prefIndex = mAppListPreferenceGroup.getPreferenceCount();
|
int prefIndex = mAppListPreferenceGroup.getPreferenceCount();
|
||||||
|
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.fuelgauge.batteryusage;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceViewHolder;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settingslib.widget.SettingsSpinnerAdapter;
|
||||||
|
|
||||||
|
/** A preference which contains a spinner. */
|
||||||
|
public class SpinnerPreference extends Preference {
|
||||||
|
private static final String TAG = "SpinnerPreference";
|
||||||
|
|
||||||
|
private AdapterView.OnItemSelectedListener mOnItemSelectedListener;
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
Spinner mSpinner;
|
||||||
|
@VisibleForTesting
|
||||||
|
String[] mItems;
|
||||||
|
@VisibleForTesting
|
||||||
|
int mSavedSpinnerPosition;
|
||||||
|
|
||||||
|
public SpinnerPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
setLayoutResource(R.layout.preference_spinner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeSpinner(
|
||||||
|
String[] items, AdapterView.OnItemSelectedListener onItemSelectedListener) {
|
||||||
|
mItems = items;
|
||||||
|
mOnItemSelectedListener = onItemSelectedListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||||
|
mSpinner = (Spinner) view.findViewById(R.id.spinner);
|
||||||
|
mSpinner.setAdapter(new SpinnerAdapter(getContext(), mItems));
|
||||||
|
mSpinner.setSelection(mSavedSpinnerPosition);
|
||||||
|
if (mOnItemSelectedListener != null) {
|
||||||
|
mSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Parcelable onSaveInstanceState() {
|
||||||
|
Log.d(TAG, "onSaveInstanceState() spinnerPosition=" + mSpinner.getSelectedItemPosition());
|
||||||
|
return new SavedState(super.onSaveInstanceState(), mSpinner.getSelectedItemPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(Parcelable state) {
|
||||||
|
if (state == null || !state.getClass().equals(SavedState.class)) {
|
||||||
|
super.onRestoreInstanceState(state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SavedState savedState = (SavedState) state;
|
||||||
|
super.onRestoreInstanceState(savedState.getSuperState());
|
||||||
|
mSavedSpinnerPosition = savedState.getSpinnerPosition();
|
||||||
|
if (mOnItemSelectedListener != null) {
|
||||||
|
mOnItemSelectedListener.onItemSelected(/* parent= */null, /* view= */null,
|
||||||
|
savedState.getSpinnerPosition(), /* id= */ 0);
|
||||||
|
}
|
||||||
|
Log.d(TAG, "onRestoreInstanceState() spinnerPosition=" + savedState.getSpinnerPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static class SavedState extends BaseSavedState {
|
||||||
|
private int mSpinnerPosition;
|
||||||
|
|
||||||
|
SavedState(Parcelable superState, int spinnerPosition) {
|
||||||
|
super(superState);
|
||||||
|
mSpinnerPosition = spinnerPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSpinnerPosition() {
|
||||||
|
return mSpinnerPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SpinnerAdapter extends SettingsSpinnerAdapter<CharSequence> {
|
||||||
|
private final String[] mItems;
|
||||||
|
|
||||||
|
SpinnerAdapter(Context context, String[] items) {
|
||||||
|
super(context);
|
||||||
|
mItems = items;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mItems.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getItem(int position) {
|
||||||
|
return mItems[position];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,152 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.fuelgauge.batteryusage;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceViewHolder;
|
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
|
||||||
import androidx.viewpager2.widget.ViewPager2;
|
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
import com.google.android.material.tabs.TabLayout;
|
|
||||||
import com.google.android.material.tabs.TabLayoutMediator;
|
|
||||||
|
|
||||||
/** A preference which contains a tab selection. */
|
|
||||||
public class TabPreference extends Preference {
|
|
||||||
private static final String TAG = "TabPreference";
|
|
||||||
|
|
||||||
private Fragment mRootFragment;
|
|
||||||
private ViewPager2 mViewPager;
|
|
||||||
private ViewPager2.OnPageChangeCallback mOnPageChangeCallback;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
String[] mTabTitles;
|
|
||||||
@VisibleForTesting
|
|
||||||
int mSavedTabPosition;
|
|
||||||
@VisibleForTesting
|
|
||||||
TabLayout mTabLayout;
|
|
||||||
|
|
||||||
public TabPreference(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
setLayoutResource(R.layout.preference_tab);
|
|
||||||
}
|
|
||||||
|
|
||||||
void initializeTabs(Fragment rootFragment, String[] tabTitles) {
|
|
||||||
mRootFragment = rootFragment;
|
|
||||||
mTabTitles = tabTitles;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOnPageChangeCallback(ViewPager2.OnPageChangeCallback callback) {
|
|
||||||
mOnPageChangeCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
|
||||||
super.onBindViewHolder(view);
|
|
||||||
if (mViewPager != null && mTabLayout != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mViewPager = (ViewPager2) view.findViewById(R.id.view_pager);
|
|
||||||
mViewPager.setAdapter(new FragmentAdapter(mRootFragment, mTabTitles.length));
|
|
||||||
mViewPager.setUserInputEnabled(false);
|
|
||||||
if (mOnPageChangeCallback != null) {
|
|
||||||
mViewPager.registerOnPageChangeCallback(mOnPageChangeCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
mTabLayout = (TabLayout) view.findViewById(R.id.tabs);
|
|
||||||
new TabLayoutMediator(
|
|
||||||
mTabLayout, mViewPager, /* autoRefresh= */ true, /* smoothScroll= */ false,
|
|
||||||
(tab, position) -> tab.setText(mTabTitles[position])).attach();
|
|
||||||
mTabLayout.getTabAt(mSavedTabPosition).select();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDetached() {
|
|
||||||
super.onDetached();
|
|
||||||
if (mViewPager != null && mOnPageChangeCallback != null) {
|
|
||||||
mViewPager.unregisterOnPageChangeCallback(mOnPageChangeCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Parcelable onSaveInstanceState() {
|
|
||||||
Log.d(TAG, "onSaveInstanceState() tabPosition=" + mTabLayout.getSelectedTabPosition());
|
|
||||||
return new SavedState(super.onSaveInstanceState(), mTabLayout.getSelectedTabPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onRestoreInstanceState(Parcelable state) {
|
|
||||||
if (state == null || !state.getClass().equals(SavedState.class)) {
|
|
||||||
super.onRestoreInstanceState(state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SavedState savedState = (SavedState) state;
|
|
||||||
super.onRestoreInstanceState(savedState.getSuperState());
|
|
||||||
mSavedTabPosition = savedState.getTabPosition();
|
|
||||||
Log.d(TAG, "onRestoreInstanceState() tabPosition=" + savedState.getTabPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
static class SavedState extends BaseSavedState {
|
|
||||||
private int mTabPosition;
|
|
||||||
|
|
||||||
SavedState(Parcelable superState, int tabPosition) {
|
|
||||||
super(superState);
|
|
||||||
mTabPosition = tabPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getTabPosition() {
|
|
||||||
return mTabPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class FragmentAdapter extends FragmentStateAdapter {
|
|
||||||
private final int mItemCount;
|
|
||||||
private final Fragment[] mItemFragments;
|
|
||||||
|
|
||||||
FragmentAdapter(@NonNull Fragment rootFragment, int itemCount) {
|
|
||||||
super(rootFragment);
|
|
||||||
mItemCount = itemCount;
|
|
||||||
mItemFragments = new Fragment[mItemCount];
|
|
||||||
for (int i = 0; i < mItemCount; i++) {
|
|
||||||
// Empty tab pages.
|
|
||||||
mItemFragments[i] = new Fragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public Fragment createFragment(int position) {
|
|
||||||
return mItemFragments[position];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return mItemCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -22,14 +22,12 @@ import static org.mockito.Mockito.doReturn;
|
|||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
|
||||||
import com.google.android.material.tabs.TabLayout;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -39,50 +37,47 @@ import org.robolectric.RobolectricTestRunner;
|
|||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public final class TabPreferenceTest {
|
public final class SpinnerPreferenceTest {
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private TabPreference mTabPreference;
|
private SpinnerPreference mSpinnerPreference;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Fragment mMockFragment;
|
private Spinner mMockSpinner;
|
||||||
@Mock
|
|
||||||
private TabLayout mMockTabLayout;
|
|
||||||
|
|
||||||
private final String[] mTabTitles = new String[]{"tab1", "tab2"};
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
mTabPreference = new TabPreference(mContext, /*attrs=*/ null);
|
mSpinnerPreference = new SpinnerPreference(mContext, /*attrs=*/ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void constructor_returnExpectedResult() {
|
public void constructor_returnExpectedResult() {
|
||||||
assertThat(mTabPreference.getLayoutResource()).isEqualTo(R.layout.preference_tab);
|
assertThat(mSpinnerPreference.getLayoutResource()).isEqualTo(R.layout.preference_spinner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void initializeTabs_returnExpectedResult() {
|
public void initializeSpinner_returnExpectedResult() {
|
||||||
mTabPreference.initializeTabs(mMockFragment, mTabTitles);
|
final String[] items = new String[]{"item1", "item2"};
|
||||||
assertThat(mTabPreference.mTabTitles).isEqualTo(mTabTitles);
|
mSpinnerPreference.initializeSpinner(items, null);
|
||||||
|
assertThat(mSpinnerPreference.mItems).isEqualTo(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onSaveInstanceState_returnExpectedResult() {
|
public void onSaveInstanceState_returnExpectedResult() {
|
||||||
doReturn(1).when(mMockTabLayout).getSelectedTabPosition();
|
doReturn(1).when(mMockSpinner).getSelectedItemPosition();
|
||||||
mTabPreference.mTabLayout = mMockTabLayout;
|
mSpinnerPreference.mSpinner = mMockSpinner;
|
||||||
TabPreference.SavedState savedState =
|
SpinnerPreference.SavedState savedState =
|
||||||
(TabPreference.SavedState) mTabPreference.onSaveInstanceState();
|
(SpinnerPreference.SavedState) mSpinnerPreference.onSaveInstanceState();
|
||||||
assertThat(savedState.getTabPosition()).isEqualTo(1);
|
assertThat(savedState.getSpinnerPosition()).isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onRestoreInstanceState_returnExpectedResult() {
|
public void onRestoreInstanceState_returnExpectedResult() {
|
||||||
TabPreference.SavedState savedState =
|
SpinnerPreference.SavedState savedState =
|
||||||
new TabPreference.SavedState(Preference.BaseSavedState.EMPTY_STATE, 2);
|
new SpinnerPreference.SavedState(Preference.BaseSavedState.EMPTY_STATE, 2);
|
||||||
mTabPreference.onRestoreInstanceState(savedState);
|
mSpinnerPreference.onRestoreInstanceState(savedState);
|
||||||
assertThat(mTabPreference.mSavedTabPosition).isEqualTo(2);
|
assertThat(mSpinnerPreference.mSavedSpinnerPosition).isEqualTo(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user