1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.fuelgauge.batteryusage;
18 
19 import android.content.Context;
20 import android.os.Parcelable;
21 import android.util.AttributeSet;
22 import android.util.Log;
23 import android.widget.AdapterView;
24 import android.widget.Spinner;
25 
26 import androidx.preference.Preference;
27 import androidx.preference.PreferenceViewHolder;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 import com.android.settings.R;
31 import com.android.settingslib.widget.SettingsSpinnerAdapter;
32 
33 /** A preference which contains a spinner. */
34 public class SpinnerPreference extends Preference {
35     private static final String TAG = "SpinnerPreference";
36 
37     private AdapterView.OnItemSelectedListener mOnItemSelectedListener;
38 
39     @VisibleForTesting Spinner mSpinner;
40     @VisibleForTesting String[] mItems;
41     @VisibleForTesting int mSavedSpinnerPosition;
42 
SpinnerPreference(Context context, AttributeSet attrs)43     public SpinnerPreference(Context context, AttributeSet attrs) {
44         super(context, attrs);
45         setLayoutResource(R.layout.preference_spinner);
46     }
47 
initializeSpinner( String[] items, AdapterView.OnItemSelectedListener onItemSelectedListener)48     void initializeSpinner(
49             String[] items, AdapterView.OnItemSelectedListener onItemSelectedListener) {
50         mItems = items;
51         mOnItemSelectedListener = onItemSelectedListener;
52     }
53 
54     @Override
onBindViewHolder(PreferenceViewHolder view)55     public void onBindViewHolder(PreferenceViewHolder view) {
56         if (mSpinner != null) {
57             return;
58         }
59 
60         mSpinner = (Spinner) view.findViewById(R.id.spinner);
61         mSpinner.setAdapter(new SpinnerAdapter(getContext(), mItems));
62         mSpinner.setSelection(mSavedSpinnerPosition);
63         mSpinner.setLongClickable(false);
64         if (mOnItemSelectedListener != null) {
65             mSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
66         }
67     }
68 
69     @Override
onSaveInstanceState()70     protected Parcelable onSaveInstanceState() {
71         if (mSpinner == null) {
72             return super.onSaveInstanceState();
73         }
74         Log.d(TAG, "onSaveInstanceState() spinnerPosition=" + mSpinner.getSelectedItemPosition());
75         return new SavedState(super.onSaveInstanceState(), mSpinner.getSelectedItemPosition());
76     }
77 
78     @Override
onRestoreInstanceState(Parcelable state)79     protected void onRestoreInstanceState(Parcelable state) {
80         if (state == null || state == BaseSavedState.EMPTY_STATE) {
81             super.onRestoreInstanceState(state);
82             return;
83         }
84         if (!(state instanceof SavedState)) {
85             // To avoid the IllegalArgumentException, return the BaseSavedState.EMPTY_STATE.
86             super.onRestoreInstanceState(BaseSavedState.EMPTY_STATE);
87             return;
88         }
89         SavedState savedState = (SavedState) state;
90         super.onRestoreInstanceState(savedState.getSuperState());
91         mSavedSpinnerPosition = savedState.getSpinnerPosition();
92         if (mOnItemSelectedListener != null) {
93             mOnItemSelectedListener.onItemSelected(
94                     /* parent= */ null,
95                     /* view= */ null,
96                     savedState.getSpinnerPosition(),
97                     /* id= */ 0);
98         }
99         Log.d(TAG, "onRestoreInstanceState() spinnerPosition=" + savedState.getSpinnerPosition());
100     }
101 
102     @VisibleForTesting
103     static class SavedState extends BaseSavedState {
104         private int mSpinnerPosition;
105 
SavedState(Parcelable superState, int spinnerPosition)106         SavedState(Parcelable superState, int spinnerPosition) {
107             super(superState);
108             mSpinnerPosition = spinnerPosition;
109         }
110 
getSpinnerPosition()111         int getSpinnerPosition() {
112             return mSpinnerPosition;
113         }
114     }
115 
116     private static class SpinnerAdapter extends SettingsSpinnerAdapter<CharSequence> {
117         private final String[] mItems;
118 
SpinnerAdapter(Context context, String[] items)119         SpinnerAdapter(Context context, String[] items) {
120             super(context);
121             mItems = items;
122         }
123 
124         @Override
getCount()125         public int getCount() {
126             return mItems.length;
127         }
128 
129         @Override
getItem(int position)130         public CharSequence getItem(int position) {
131             return mItems[position];
132         }
133     }
134 }
135