• 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.os.Bundle;
20 import android.text.TextUtils;
21 import android.view.LayoutInflater;
22 import android.view.View;
23 import android.view.ViewGroup;
24 
25 import androidx.annotation.NonNull;
26 import androidx.annotation.Nullable;
27 import androidx.annotation.VisibleForTesting;
28 import androidx.annotation.XmlRes;
29 import androidx.fragment.app.DialogFragment;
30 import androidx.fragment.app.Fragment;
31 import androidx.fragment.app.FragmentActivity;
32 import androidx.fragment.app.FragmentManager;
33 import androidx.preference.Preference;
34 import androidx.preference.PreferenceScreen;
35 import androidx.recyclerview.widget.RecyclerView;
36 
37 import com.android.car.settings.R;
38 
39 import java.util.List;
40 
41 /**
42  * Top level settings menu.
43  */
44 public class TopLevelMenuFragment extends SettingsFragment {
45 
46     /**
47      * The preference key for the top-level menu item associated with a fragment.
48      * This is intended to be included with fragments launched from top-level menu
49      * preferences using the {@link #launchFragment} method.
50      */
51     public static final String FRAGMENT_MENU_PREFERENCE_KEY = "fragment_menu_preference_key";
52 
53     private static final String KEY_SAVED_SELECTED_PREFERENCE_KEY = "saved_selected_preference_key";
54 
55     private String mSelectedPreferenceKey;
56 
57     @Override
58     @XmlRes
getPreferenceScreenResId()59     protected int getPreferenceScreenResId() {
60         return R.xml.homepage_fragment;
61     }
62 
63     @Override
onViewCreated(@onNull View view, @Nullable Bundle savedInstanceState)64     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
65         super.onViewCreated(view, savedInstanceState);
66         if (savedInstanceState != null
67                 && savedInstanceState.getString(KEY_SAVED_SELECTED_PREFERENCE_KEY) != null) {
68             updatePreferenceHighlight(
69                     savedInstanceState.getString(KEY_SAVED_SELECTED_PREFERENCE_KEY));
70         } else {
71             updatePreferenceHighlight(getActivity().getIntent()
72                     .getStringExtra(BaseCarSettingsActivity.META_DATA_KEY_HEADER_KEY));
73         }
74     }
75 
76     @Override
onSaveInstanceState(@onNull Bundle outState)77     public void onSaveInstanceState(@NonNull Bundle outState) {
78         super.onSaveInstanceState(outState);
79         outState.putString(KEY_SAVED_SELECTED_PREFERENCE_KEY, mSelectedPreferenceKey);
80     }
81 
82     @Override
onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)83     public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
84             Bundle savedInstanceState) {
85         inflater.inflate(R.layout.top_level_recyclerview, parent, /* attachToRoot= */ true);
86         return parent.requireViewById(R.id.top_level_recycler_view);
87     }
88 
89     @Override
launchFragment(@ullable Fragment fragment)90     public void launchFragment(@Nullable Fragment fragment) {
91         if (fragment == null) {
92             return;
93         }
94         String preferenceKey = null;
95         if (fragment.getArguments() != null) {
96             preferenceKey = fragment.getArguments().getString(FRAGMENT_MENU_PREFERENCE_KEY);
97         }
98         if (TextUtils.equals(getCurrentFragmentClass(), fragment.getClass().getName())
99                 && TextUtils.equals(preferenceKey, mSelectedPreferenceKey)) {
100             // Do nothing - already at the location being navigated to.
101             return;
102         }
103         clearBackStack();
104         updatePreferenceHighlight(preferenceKey);
105         super.launchFragment(fragment);
106     }
107 
108     @Override
onPreferenceTreeClick(Preference preference)109     public boolean onPreferenceTreeClick(Preference preference) {
110         if (preference.getFragment() == null) {
111             // No fragment provided - likely launching a new activity.
112             return super.onPreferenceTreeClick(preference);
113         }
114         if (TextUtils.equals(getCurrentFragmentClass(), preference.getFragment())
115                 && TextUtils.equals(preference.getKey(), mSelectedPreferenceKey)) {
116             // Do nothing - already at the location being navigated to.
117             return true;
118         }
119         clearBackStack();
120         updatePreferenceHighlight(preference.getKey());
121         return super.onPreferenceTreeClick(preference);
122     }
123 
124     @Override
createHighlightableAdapter( PreferenceScreen preferenceScreen)125     protected HighlightablePreferenceGroupAdapter createHighlightableAdapter(
126             PreferenceScreen preferenceScreen) {
127         return new HighlightablePreferenceGroupAdapter(preferenceScreen,
128                 R.drawable.top_level_preference_background,
129                 R.drawable.top_level_preference_highlight);
130     }
131 
updatePreferenceHighlight(String key)132     private void updatePreferenceHighlight(String key) {
133         mSelectedPreferenceKey = key;
134         if (!TextUtils.isEmpty(mSelectedPreferenceKey)) {
135             requestPreferenceHighlight(mSelectedPreferenceKey);
136         } else {
137             clearPreferenceHighlight();
138         }
139     }
140 
141     @VisibleForTesting
getSelectedPreferenceKey()142     String getSelectedPreferenceKey() {
143         return mSelectedPreferenceKey;
144     }
145 
146     @Nullable
getCurrentFragmentClass()147     private String getCurrentFragmentClass() {
148         FragmentActivity activity = getActivity();
149         if (activity == null) {
150             return null;
151         }
152         Fragment currentFragment =
153                 activity.getSupportFragmentManager().findFragmentById(R.id.fragment_container);
154         if (currentFragment == null) {
155             return null;
156         }
157         return currentFragment.getClass().getName();
158     }
159 
clearBackStack()160     private void clearBackStack() {
161         FragmentActivity activity = getActivity();
162         if (activity == null) {
163             return;
164         }
165 
166         // dismiss dialogs
167         List<Fragment> fragments = activity.getSupportFragmentManager().getFragments();
168         for (Fragment fragment : fragments) {
169             if (fragment instanceof DialogFragment) {
170                 ((DialogFragment) fragment).dismiss();
171             }
172         }
173         // clear fragments
174         activity.getSupportFragmentManager().popBackStackImmediate(/* name= */ null,
175                 FragmentManager.POP_BACK_STACK_INCLUSIVE);
176     }
177 }
178