1 /* 2 * Copyright (C) 2019 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.car.developeroptions.wifi.calling; 18 19 import android.content.Context; 20 import android.content.DialogInterface; 21 import android.content.res.TypedArray; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.util.AttributeSet; 25 import android.util.Log; 26 import android.view.LayoutInflater; 27 import android.view.View; 28 import android.view.ViewGroup; 29 import android.widget.ArrayAdapter; 30 import android.widget.ListAdapter; 31 import android.widget.RadioButton; 32 import android.widget.TextView; 33 import androidx.appcompat.app.AlertDialog.Builder; 34 import com.android.car.developeroptions.CustomListPreference; 35 import com.android.car.developeroptions.R; 36 37 /** 38 * ListPreference contain the entry summary. 39 */ 40 public class ListWithEntrySummaryPreference extends CustomListPreference { 41 private static final String LOG_TAG = "ListWithEntrySummaryPreference"; 42 private final Context mContext; 43 private CharSequence[] mSummaries; 44 45 /** 46 * ListWithEntrySummaryPreference constructor. 47 * 48 * @param context The context of view. 49 * @param attrs The attributes of the XML tag that is inflating the linear layout. 50 */ ListWithEntrySummaryPreference(Context context, AttributeSet attrs)51 public ListWithEntrySummaryPreference(Context context, AttributeSet attrs) { 52 super(context, attrs); 53 mContext = context; 54 55 TypedArray array = context.obtainStyledAttributes(attrs, 56 R.styleable.ListWithEntrySummaryPreference, 0, 0); 57 mSummaries = array.getTextArray(R.styleable.ListWithEntrySummaryPreference_entrySummaries); 58 array.recycle(); 59 } 60 61 /** 62 * Sets the summaries of mode items to be shown in the mode select dialog. 63 * 64 * @param summariesResId The summaries of mode items. 65 */ setEntrySummaries(int summariesResId)66 public void setEntrySummaries(int summariesResId) { 67 mSummaries = getContext().getResources().getTextArray(summariesResId); 68 } 69 70 /** 71 * Sets the summaries of mode items to be shown in the mode select dialog. 72 * 73 * @param summaries The summaries of mode items. 74 */ setEntrySummaries(CharSequence[] summaries)75 public void setEntrySummaries(CharSequence[] summaries) { 76 mSummaries = summaries; 77 } 78 getEntrySummary(int index)79 private CharSequence getEntrySummary(int index) { 80 if (mSummaries == null) { 81 Log.w(LOG_TAG, "getEntrySummary : mSummaries is null"); 82 return ""; 83 } 84 return mSummaries[index]; 85 } 86 87 @Override onPrepareDialogBuilder(Builder builder, DialogInterface.OnClickListener listener)88 protected void onPrepareDialogBuilder(Builder builder, 89 DialogInterface.OnClickListener listener) { 90 ListAdapter la = (ListAdapter) new SelectorAdapter(mContext, 91 R.xml.single_choice_list_item_2, this); 92 builder.setSingleChoiceItems(la, findIndexOfValue(getValue()), listener); 93 super.onPrepareDialogBuilder(builder, listener); 94 } 95 96 private static class SelectorAdapter extends ArrayAdapter<CharSequence> { 97 private final Context mContext; 98 private ListWithEntrySummaryPreference mSelector; 99 100 /** 101 * SelectorAdapter constructor. 102 * 103 * @param context The current context. 104 * @param rowResourceId The resource id of the XML tag that is inflating the linear layout. 105 * @param listPreference The instance of ListWithEntrySummaryPreference. 106 */ SelectorAdapter(Context context, int rowResourceId, ListWithEntrySummaryPreference listPreference)107 public SelectorAdapter(Context context, int rowResourceId, 108 ListWithEntrySummaryPreference listPreference) { 109 super(context, rowResourceId, listPreference.getEntryValues()); 110 mContext = context; 111 mSelector = listPreference; 112 } 113 114 @Override getView(int position, View convertView, ViewGroup parent)115 public View getView(int position, View convertView, ViewGroup parent) { 116 LayoutInflater inflater = LayoutInflater.from(mContext); 117 View row = inflater.inflate(R.xml.single_choice_list_item_2, parent, false); 118 119 TextView title = (TextView) row.findViewById(R.id.title); 120 title.setText(mSelector.getEntries()[position]); 121 122 TextView summary = (TextView) row.findViewById(R.id.summary); 123 summary.setText(mSelector.getEntrySummary(position)); 124 125 RadioButton rb = (RadioButton) row.findViewById(R.id.radio); 126 if (position == mSelector.findIndexOfValue(mSelector.getValue())) { 127 rb.setChecked(true); 128 } 129 130 return row; 131 } 132 } 133 134 @Override onSaveInstanceState()135 protected Parcelable onSaveInstanceState() { 136 final Parcelable superState = super.onSaveInstanceState(); 137 138 final SavedState myState = new SavedState(superState); 139 myState.mEntries = getEntries(); 140 myState.mEntryValues = getEntryValues(); 141 myState.mSummaries = mSummaries; 142 return myState; 143 } 144 145 @Override onRestoreInstanceState(Parcelable state)146 protected void onRestoreInstanceState(Parcelable state) { 147 if (state == null || !state.getClass().equals(SavedState.class)) { 148 // Didn't save state for us in onSaveInstanceState 149 super.onRestoreInstanceState(state); 150 return; 151 } 152 153 SavedState myState = (SavedState) state; 154 super.onRestoreInstanceState(myState.getSuperState()); 155 setEntries(myState.mEntries); 156 setEntryValues(myState.mEntryValues); 157 mSummaries = myState.mSummaries; 158 } 159 160 /** 161 * We save entries, entryValues and summaries into bundle. 162 * At onCreate of fragment, dialog will be restored if it was open. In this case, 163 * we need to restore entries, entryValues and summaries. Without those information, 164 * crash when entering multi window during wfc modes dialog shown. 165 */ 166 private static class SavedState extends BaseSavedState { 167 private CharSequence[] mEntries; 168 private CharSequence[] mEntryValues; 169 private CharSequence[] mSummaries; 170 SavedState(Parcel source)171 public SavedState(Parcel source) { 172 super(source); 173 mEntries = source.readCharSequenceArray(); 174 mEntryValues = source.readCharSequenceArray(); 175 mSummaries = source.readCharSequenceArray(); 176 } 177 178 @Override writeToParcel(Parcel dest, int flags)179 public void writeToParcel(Parcel dest, int flags) { 180 super.writeToParcel(dest, flags); 181 dest.writeCharSequenceArray(mEntries); 182 dest.writeCharSequenceArray(mEntryValues); 183 dest.writeCharSequenceArray(mSummaries); 184 } 185 SavedState(Parcelable superState)186 public SavedState(Parcelable superState) { 187 super(superState); 188 } 189 190 public static final Parcelable.Creator<SavedState> CREATOR = 191 new Parcelable.Creator<SavedState>() { 192 @Override 193 public SavedState createFromParcel(Parcel in) { 194 return new SavedState(in); 195 } 196 197 @Override 198 public SavedState[] newArray(int size) { 199 return new SavedState[size]; 200 } 201 }; 202 } 203 } 204