1 /*
2  * Copyright 2018 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 androidx.leanback.preference;
18 
19 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
20 
21 import android.content.Context;
22 import android.os.Bundle;
23 import android.util.TypedValue;
24 import android.view.ContextThemeWrapper;
25 import android.view.LayoutInflater;
26 import android.view.ViewGroup;
27 
28 import androidx.annotation.RestrictTo;
29 import androidx.fragment.app.Fragment;
30 import androidx.leanback.widget.VerticalGridView;
31 import androidx.preference.PreferenceFragmentCompat;
32 import androidx.preference.PreferenceRecyclerViewAccessibilityDelegate;
33 import androidx.recyclerview.widget.RecyclerView;
34 
35 import org.jspecify.annotations.Nullable;
36 
37 /**
38  * This fragment provides a preference fragment with leanback-style behavior, suitable for
39  * embedding into broader UI elements.
40  */
41 public abstract class BaseLeanbackPreferenceFragmentCompat extends PreferenceFragmentCompat {
42 
43     private Context mThemedContext;
44 
45     @Override
getContext()46     public @Nullable Context getContext() {
47         if (mThemedContext == null && getActivity() != null) {
48             final TypedValue tv = new TypedValue();
49             getActivity().getTheme().resolveAttribute(
50                     androidx.preference.R.attr.preferenceTheme, tv, true);
51             int theme = tv.resourceId;
52             if (theme == 0) {
53                 // Fallback to default theme.
54                 theme = R.style.PreferenceThemeOverlayLeanback;
55             }
56             // aosp/821989 has forced PreferenceFragment to use the theme of activity and only
57             // override theme attribute value when it's not defined in activity theme.
58             // However, a side panel preference fragment can use different values than main content.
59             // So a ContextThemeWrapper is required, overrides getContext() before
60             // super.onCreate() call to use the ContextThemeWrapper in creating PreferenceManager
61             // and onCreateView().
62             // super.onCreate() will apply() the theme to activity in non-force way, which shouldn't
63             // affect activity as the theme attributes of PreferenceThemeOverlayLeanback is already
64             // in the activity's theme (in framework)
65             mThemedContext = new ContextThemeWrapper(super.getContext(), theme);
66         }
67         return mThemedContext;
68     }
69 
70     @Override
onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)71     public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
72             Bundle savedInstanceState) {
73         VerticalGridView verticalGridView = (VerticalGridView) inflater
74                 .inflate(R.layout.leanback_preferences_list, parent, false);
75         verticalGridView.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
76         verticalGridView.setFocusScrollStrategy(VerticalGridView.FOCUS_SCROLL_ALIGNED);
77         verticalGridView.setAccessibilityDelegateCompat(
78                 new PreferenceRecyclerViewAccessibilityDelegate(verticalGridView));
79         return verticalGridView;
80     }
81 
82     /**
83      */
84     @RestrictTo(LIBRARY_GROUP_PREFIX)
85     @Override
getCallbackFragment()86     public Fragment getCallbackFragment() {
87         return getParentFragment();
88     }
89 }
90