• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.settings.common;
18 
19 import android.content.Context;
20 import android.util.TypedValue;
21 import android.view.View;
22 
23 import androidx.annotation.DrawableRes;
24 import androidx.preference.PreferenceGroup;
25 import androidx.preference.PreferenceGroupAdapter;
26 import androidx.preference.PreferenceViewHolder;
27 import androidx.recyclerview.widget.RecyclerView;
28 
29 import com.android.car.settings.R;
30 
31 /** RecyclerView adapter that supports single-preference highlighting. */
32 public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter {
33 
34     @DrawableRes
35     private final int mNormalBackgroundRes;
36     @DrawableRes
37     private final int mHighlightBackgroundRes;
38     private int mHighlightPosition = RecyclerView.NO_POSITION;
39 
HighlightablePreferenceGroupAdapter(PreferenceGroup preferenceGroup)40     public HighlightablePreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
41         super(preferenceGroup);
42         Context context = preferenceGroup.getContext();
43         TypedValue outValue = new TypedValue();
44         context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
45                 outValue, /* resolveRefs= */ true);
46         mNormalBackgroundRes = outValue.resourceId;
47         mHighlightBackgroundRes = R.drawable.preference_highlight_default;
48     }
49 
HighlightablePreferenceGroupAdapter(PreferenceGroup preferenceGroup, @DrawableRes int normalBackgroundRes, @DrawableRes int highlightBackgroundRes)50     public HighlightablePreferenceGroupAdapter(PreferenceGroup preferenceGroup,
51             @DrawableRes int normalBackgroundRes, @DrawableRes int highlightBackgroundRes) {
52         super(preferenceGroup);
53         mNormalBackgroundRes = normalBackgroundRes;
54         mHighlightBackgroundRes = highlightBackgroundRes;
55     }
56 
57     @Override
onBindViewHolder(PreferenceViewHolder holder, int position)58     public void onBindViewHolder(PreferenceViewHolder holder, int position) {
59         super.onBindViewHolder(holder, position);
60         updateBackground(holder, position);
61     }
62 
updateBackground(PreferenceViewHolder holder, int position)63     private void updateBackground(PreferenceViewHolder holder, int position) {
64         View v = holder.itemView;
65         if (position == mHighlightPosition) {
66             addHighlightBackground(v);
67         } else if (hasHighlightBackground(v)) {
68             removeHighlightBackground(v);
69         }
70     }
71 
72     /**
73      * Requests that a particular preference be highlighted. This will remove the highlight from
74      * the previously highlighted preference.
75      */
requestHighlight(View root, RecyclerView recyclerView, String key)76     public void requestHighlight(View root, RecyclerView recyclerView, String key) {
77         if (root == null || recyclerView == null) {
78             return;
79         }
80         int position = getPreferenceAdapterPosition(key);
81         if (position < 0) {
82             // Item is not in the list - clearing the previous highlight without setting a new one.
83             clearHighlight(root);
84             return;
85         }
86         root.post(() -> {
87             recyclerView.scrollToPosition(position);
88             int oldPosition = mHighlightPosition;
89             mHighlightPosition = position;
90             notifyItemChanged(oldPosition);
91             notifyItemChanged(position);
92         });
93     }
94 
95     /**
96      * Removes the highlight from the currently highlighted preference.
97      */
clearHighlight(View root)98     public void clearHighlight(View root) {
99         if (root == null) {
100             return;
101         }
102         root.post(() -> {
103             if (mHighlightPosition < 0) {
104                 return;
105             }
106             int oldPosition = mHighlightPosition;
107             mHighlightPosition = RecyclerView.NO_POSITION;
108             notifyItemChanged(oldPosition);
109         });
110     }
111 
addHighlightBackground(View v)112     private void addHighlightBackground(View v) {
113         v.setTag(R.id.preference_highlighted, true);
114         v.setBackgroundResource(mHighlightBackgroundRes);
115     }
116 
removeHighlightBackground(View v)117     private void removeHighlightBackground(View v) {
118         v.setTag(R.id.preference_highlighted, false);
119         v.setBackgroundResource(mNormalBackgroundRes);
120     }
121 
hasHighlightBackground(View v)122     private boolean hasHighlightBackground(View v) {
123         return Boolean.TRUE.equals(v.getTag(R.id.preference_highlighted));
124     }
125 }
126