/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.car.settings.common; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.annotation.XmlRes; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import androidx.recyclerview.widget.RecyclerView; import com.android.car.settings.R; import java.util.List; /** * Top level settings menu. */ public class TopLevelMenuFragment extends SettingsFragment { /** * The preference key for the top-level menu item associated with a fragment. * This is intended to be included with fragments launched from top-level menu * preferences using the {@link #launchFragment} method. */ public static final String FRAGMENT_MENU_PREFERENCE_KEY = "fragment_menu_preference_key"; private static final String KEY_SAVED_SELECTED_PREFERENCE_KEY = "saved_selected_preference_key"; private String mSelectedPreferenceKey; @Override @XmlRes protected int getPreferenceScreenResId() { return R.xml.homepage_fragment; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (savedInstanceState != null && savedInstanceState.getString(KEY_SAVED_SELECTED_PREFERENCE_KEY) != null) { updatePreferenceHighlight( savedInstanceState.getString(KEY_SAVED_SELECTED_PREFERENCE_KEY)); } else { updatePreferenceHighlight(getActivity().getIntent() .getStringExtra(BaseCarSettingsActivity.META_DATA_KEY_HEADER_KEY)); } } @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putString(KEY_SAVED_SELECTED_PREFERENCE_KEY, mSelectedPreferenceKey); } @Override public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { inflater.inflate(R.layout.top_level_recyclerview, parent, /* attachToRoot= */ true); return parent.requireViewById(R.id.top_level_recycler_view); } @Override public void launchFragment(@Nullable Fragment fragment) { if (fragment == null) { return; } String preferenceKey = null; if (fragment.getArguments() != null) { preferenceKey = fragment.getArguments().getString(FRAGMENT_MENU_PREFERENCE_KEY); } if (TextUtils.equals(getCurrentFragmentClass(), fragment.getClass().getName()) && TextUtils.equals(preferenceKey, mSelectedPreferenceKey)) { // Do nothing - already at the location being navigated to. return; } clearBackStack(); updatePreferenceHighlight(preferenceKey); super.launchFragment(fragment); } @Override public boolean onPreferenceTreeClick(Preference preference) { if (preference.getFragment() == null) { // No fragment provided - likely launching a new activity. return super.onPreferenceTreeClick(preference); } if (TextUtils.equals(getCurrentFragmentClass(), preference.getFragment()) && TextUtils.equals(preference.getKey(), mSelectedPreferenceKey)) { // Do nothing - already at the location being navigated to. return true; } clearBackStack(); updatePreferenceHighlight(preference.getKey()); return super.onPreferenceTreeClick(preference); } @Override protected HighlightablePreferenceGroupAdapter createHighlightableAdapter( PreferenceScreen preferenceScreen) { return new HighlightablePreferenceGroupAdapter(preferenceScreen, R.drawable.top_level_preference_background, R.drawable.top_level_preference_highlight); } private void updatePreferenceHighlight(String key) { mSelectedPreferenceKey = key; if (!TextUtils.isEmpty(mSelectedPreferenceKey)) { requestPreferenceHighlight(mSelectedPreferenceKey); } else { clearPreferenceHighlight(); } } @VisibleForTesting String getSelectedPreferenceKey() { return mSelectedPreferenceKey; } @Nullable private String getCurrentFragmentClass() { FragmentActivity activity = getActivity(); if (activity == null) { return null; } Fragment currentFragment = activity.getSupportFragmentManager().findFragmentById(R.id.fragment_container); if (currentFragment == null) { return null; } return currentFragment.getClass().getName(); } private void clearBackStack() { FragmentActivity activity = getActivity(); if (activity == null) { return; } // dismiss dialogs List fragments = activity.getSupportFragmentManager().getFragments(); for (Fragment fragment : fragments) { if (fragment instanceof DialogFragment) { ((DialogFragment) fragment).dismiss(); } } // clear fragments activity.getSupportFragmentManager().popBackStackImmediate(/* name= */ null, FragmentManager.POP_BACK_STACK_INCLUSIVE); } }