• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.tv.twopanelsettings;
18 
19 import android.animation.AnimatorInflater;
20 import android.os.Bundle;
21 import android.text.TextUtils;
22 import android.view.LayoutInflater;
23 import android.view.View;
24 import android.view.ViewGroup;
25 import android.widget.TextView;
26 
27 import androidx.preference.DialogPreference;
28 import androidx.preference.ListPreference;
29 import androidx.preference.MultiSelectListPreference;
30 import androidx.recyclerview.widget.RecyclerView;
31 
32 
33 /** A workaround for pi-tv-dev to fix the issue that ListPreference is not correctly handled by two
34  * panel lib. When moving to Q, we should fix this problem in androidx(b/139085296).
35  */
36 public class TwoPanelListPreferenceDialogFragment extends
37         LeanbackListPreferenceDialogFragmentCompat {
38     private static final String SAVE_STATE_IS_MULTI =
39             "LeanbackListPreferenceDialogFragment.isMulti";
40     private static final String SAVE_STATE_ENTRIES = "LeanbackListPreferenceDialogFragment.entries";
41     private static final String SAVE_STATE_ENTRY_VALUES =
42             "LeanbackListPreferenceDialogFragment.entryValues";
43     private static final String SAVE_STATE_SUMMARIES =
44             "LeanbackListPreferenceDialogFragment.summaries";
45     private static final String SAVE_STATE_INITIAL_SELECTION =
46             "LeanbackListPreferenceDialogFragment.initialSelection";
47     private boolean mMultiCopy;
48     private CharSequence[] mEntriesCopy;
49     private CharSequence[] mEntryValuesCopy;
50     private CharSequence[] mSummariesCopy;
51     private String mInitialSelectionCopy;
52 
53     /** Provide a ListPreferenceDialogFragment which satisfy the use of two panel lib **/
newInstanceSingle(String key)54     public static TwoPanelListPreferenceDialogFragment newInstanceSingle(String key) {
55         final Bundle args = new Bundle(1);
56         args.putString(ARG_KEY, key);
57 
58         final TwoPanelListPreferenceDialogFragment
59                 fragment = new TwoPanelListPreferenceDialogFragment();
60         fragment.setArguments(args);
61 
62         return fragment;
63     }
64 
65     @Override
onCreate(Bundle savedInstanceState)66     public void onCreate(Bundle savedInstanceState) {
67         super.onCreate(savedInstanceState);
68         if (savedInstanceState == null) {
69             final DialogPreference preference = getPreference();
70             if (preference instanceof ListPreference) {
71                 mMultiCopy = false;
72                 mEntriesCopy = ((ListPreference) preference).getEntries();
73                 mEntryValuesCopy = ((ListPreference) preference).getEntryValues();
74                 if (preference instanceof SummaryListPreference) {
75                     mSummariesCopy = ((SummaryListPreference) preference).getSummaries();
76                 }
77                 mInitialSelectionCopy = ((ListPreference) preference).getValue();
78             } else if (preference instanceof MultiSelectListPreference) {
79                 mMultiCopy = true;
80             } else {
81                 throw new IllegalArgumentException("Preference must be a ListPreference or "
82                     + "MultiSelectListPreference");
83             }
84         } else {
85             mMultiCopy = savedInstanceState.getBoolean(SAVE_STATE_IS_MULTI);
86             mEntriesCopy = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRIES);
87             mEntryValuesCopy = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES);
88             mSummariesCopy = savedInstanceState.getCharSequenceArray(SAVE_STATE_SUMMARIES);
89             if (!mMultiCopy) {
90                 mInitialSelectionCopy = savedInstanceState.getString(SAVE_STATE_INITIAL_SELECTION);
91             }
92         }
93     }
94 
95     @Override
onViewCreated(View view, Bundle savedInstanceState)96     public void onViewCreated(View view, Bundle savedInstanceState) {
97         super.onViewCreated(view, savedInstanceState);
98         if (view != null) {
99             removeAnimationClipping(view);
100             ViewGroup mainFrame = view.findViewById(R.id.main_frame);
101             if (mainFrame != null) {
102                 mainFrame.setOutlineProvider(null);
103             }
104         }
105     }
106 
removeAnimationClipping(View v)107     protected void removeAnimationClipping(View v) {
108         if (v instanceof ViewGroup) {
109             ((ViewGroup) v).setClipChildren(false);
110             ((ViewGroup) v).setClipToPadding(false);
111             for (int index = 0; index < ((ViewGroup) v).getChildCount(); index++) {
112                 View child = ((ViewGroup) v).getChildAt(index);
113                 removeAnimationClipping(child);
114             }
115         }
116     }
117 
118     @Override
onCreateAdapter()119     public RecyclerView.Adapter onCreateAdapter() {
120         if (!mMultiCopy) {
121             return new TwoPanelAdapterSingle(mEntriesCopy, mEntryValuesCopy, mSummariesCopy,
122                     mInitialSelectionCopy);
123         }
124         return super.onCreateAdapter();
125     }
126 
127     private class TwoPanelAdapterSingle extends RecyclerView.Adapter<ViewHolder>
128             implements OnItemClickListener  {
129         private final CharSequence[] mEntries;
130         private final CharSequence[] mEntryValues;
131         private final CharSequence[] mSummaries;
132         private CharSequence mSelectedValue;
133 
TwoPanelAdapterSingle(CharSequence[] entries, CharSequence[] entryValues, CharSequence[] summaries, CharSequence selectedValue)134         TwoPanelAdapterSingle(CharSequence[] entries, CharSequence[] entryValues,
135                 CharSequence[] summaries, CharSequence selectedValue) {
136             mEntries = entries;
137             mEntryValues = entryValues;
138             mSummaries = summaries;
139             mSelectedValue = selectedValue;
140         }
141 
142         @Override
onCreateViewHolder(ViewGroup parent, int viewType)143         public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
144             final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
145             final View view = inflater.inflate(R.layout.leanback_list_preference_item_single,
146                     parent, false);
147             return new ViewHolder(view, this);
148         }
149 
150         @Override
onBindViewHolder(ViewHolder holder, int position)151         public void onBindViewHolder(ViewHolder holder, int position) {
152             holder.getWidgetView().setChecked(mEntryValues[position].equals(mSelectedValue));
153             holder.getTitleView().setText(mEntries[position]);
154             holder.itemView.setStateListAnimator(AnimatorInflater.loadStateListAnimator(
155                     getContext(), R.animator.preference));
156             TextView summaryView = (TextView) holder.getContainer()
157                     .findViewById(android.R.id.summary);
158             if (summaryView != null) {
159                 if (mSummaries != null && !TextUtils.isEmpty(mSummaries[position])) {
160                     summaryView.setText(mSummaries[position]);
161                     summaryView.setVisibility(View.VISIBLE);
162                 } else {
163                     summaryView.setVisibility(View.GONE);
164                 }
165             }
166         }
167 
168         @Override
getItemCount()169         public int getItemCount() {
170             return mEntries.length;
171         }
172 
173         @Override
onItemClick(ViewHolder viewHolder)174         public void onItemClick(ViewHolder viewHolder) {
175             final int index = viewHolder.getAdapterPosition();
176             if (index == RecyclerView.NO_POSITION) {
177                 return;
178             }
179             final CharSequence entry = mEntryValues[index];
180             final ListPreference preference = (ListPreference) getPreference();
181             if (index >= 0) {
182                 String value = mEntryValues[index].toString();
183                 if (preference.callChangeListener(value)) {
184                     preference.setValue(value);
185                     mSelectedValue = entry;
186                 }
187             }
188 
189             if (getParentFragment() instanceof TwoPanelSettingsFragment) {
190                 TwoPanelSettingsFragment parent = (TwoPanelSettingsFragment) getParentFragment();
191                 parent.navigateBack();
192             }
193             notifyDataSetChanged();
194         }
195     }
196 }
197