1 /* 2 * Copyright (C) 2017 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 static com.android.car.settings.common.BaseCarSettingsActivity.META_DATA_KEY_SINGLE_PANE; 20 21 import android.car.drivingstate.CarUxRestrictions; 22 import android.car.drivingstate.CarUxRestrictionsManager; 23 import android.content.Context; 24 import android.os.Bundle; 25 import android.view.LayoutInflater; 26 import android.view.View; 27 import android.view.ViewGroup; 28 29 import androidx.annotation.LayoutRes; 30 import androidx.annotation.NonNull; 31 import androidx.annotation.StringRes; 32 import androidx.core.graphics.Insets; 33 import androidx.core.view.OnApplyWindowInsetsListener; 34 import androidx.core.view.ViewCompat; 35 import androidx.core.view.WindowInsetsCompat; 36 import androidx.fragment.app.Fragment; 37 38 import com.android.car.settings.R; 39 import com.android.car.ui.toolbar.MenuItem; 40 import com.android.car.ui.toolbar.NavButtonMode; 41 import com.android.car.ui.toolbar.ToolbarController; 42 43 import java.util.List; 44 45 /** 46 * Base fragment for setting activity. 47 */ 48 public abstract class BaseFragment extends Fragment implements 49 CarUxRestrictionsManager.OnUxRestrictionsChangedListener { 50 51 /** 52 * Return the {@link FragmentHost}. 53 */ getFragmentHost()54 public final FragmentHost getFragmentHost() { 55 return (FragmentHost) requireActivity(); 56 } 57 58 /** 59 * Assume The activity holds this fragment also implements the UxRestrictionsProvider. 60 * This function should be called after onAttach() 61 */ getCurrentRestrictions()62 protected final CarUxRestrictions getCurrentRestrictions() { 63 return ((UxRestrictionsProvider) getActivity()).getCarUxRestrictions(); 64 } 65 66 /** 67 * Checks if this fragment can be shown or not given the CarUxRestrictions. Default to 68 * {@code false} if UX_RESTRICTIONS_NO_SETUP is set. 69 */ canBeShown(@onNull CarUxRestrictions carUxRestrictions)70 protected boolean canBeShown(@NonNull CarUxRestrictions carUxRestrictions) { 71 return !CarUxRestrictionsHelper.isNoSetup(carUxRestrictions); 72 } 73 74 @Override onUxRestrictionsChanged(CarUxRestrictions restrictionInfo)75 public void onUxRestrictionsChanged(CarUxRestrictions restrictionInfo) { 76 } 77 78 /** 79 * Returns the layout id of the current Fragment. 80 */ 81 @LayoutRes getLayoutId()82 protected abstract int getLayoutId(); 83 84 /** 85 * Returns the string id for the current Fragment title. Subclasses should override this 86 * method to set the title to display. Use {@link #getToolbar().setTitle(CharSequence)} to 87 * update the displayed title while resumed. The default title is the Settings Activity label. 88 */ 89 @StringRes getTitleId()90 protected int getTitleId() { 91 return R.string.settings_label; 92 } 93 94 /** 95 * Returns the MenuItems to display in the toolbar. Subclasses should override this to 96 * add additional buttons, switches, ect. to the toolbar. 97 */ getToolbarMenuItems()98 protected List<MenuItem> getToolbarMenuItems() { 99 return null; 100 } 101 getToolbarNavButtonStyle()102 protected NavButtonMode getToolbarNavButtonStyle() { 103 return NavButtonMode.BACK; 104 } 105 getToolbar()106 protected final ToolbarController getToolbar() { 107 return getFragmentHost().getToolbar(); 108 } 109 110 /** 111 * Listen for changes to the IME insets, adjusting the rootview bottom padding to prevent the 112 * content from being hidden by the keyboard. 113 */ setupImeInsetListener(View rootView)114 protected final void setupImeInsetListener(View rootView) { 115 ViewCompat.setOnApplyWindowInsetsListener(rootView, new OnApplyWindowInsetsListener() { 116 @NonNull 117 @Override 118 public WindowInsetsCompat onApplyWindowInsets(@NonNull View view, 119 @NonNull WindowInsetsCompat windowInsetsCompat) { 120 Insets keyboardInsets = windowInsetsCompat.getInsets(WindowInsetsCompat.Type.ime()); 121 122 view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), 123 keyboardInsets.bottom); 124 return WindowInsetsCompat.CONSUMED; 125 } 126 }); 127 } 128 129 @Override onAttach(Context context)130 public void onAttach(Context context) { 131 super.onAttach(context); 132 if (!(getActivity() instanceof FragmentHost)) { 133 throw new IllegalStateException("Must attach to a FragmentHost"); 134 } 135 if (!(getActivity() instanceof UxRestrictionsProvider)) { 136 throw new IllegalStateException("Must attach to a UxRestrictionsProvider"); 137 } 138 } 139 140 @Override onCreateView(@onNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)141 public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, 142 Bundle savedInstanceState) { 143 @LayoutRes int layoutId = getLayoutId(); 144 return inflater.inflate(layoutId, container, false); 145 } 146 147 @Override onActivityCreated(Bundle savedInstanceState)148 public void onActivityCreated(Bundle savedInstanceState) { 149 super.onActivityCreated(savedInstanceState); 150 ToolbarController toolbar = getToolbar(); 151 if (toolbar != null) { 152 List<MenuItem> items = getToolbarMenuItems(); 153 if (items != null) { 154 if (items.size() == 1) { 155 items.get(0).setId(R.id.toolbar_menu_item_0); 156 } else if (items.size() == 2) { 157 items.get(0).setId(R.id.toolbar_menu_item_0); 158 items.get(1).setId(R.id.toolbar_menu_item_1); 159 } 160 } 161 toolbar.setTitle(getTitleId()); 162 toolbar.setMenuItems(items); 163 if (getActivity().getIntent().getBooleanExtra(META_DATA_KEY_SINGLE_PANE, false)) { 164 toolbar.setNavButtonMode(getToolbarNavButtonStyle()); 165 } 166 } 167 } 168 169 @Override onStart()170 public void onStart() { 171 super.onStart(); 172 onUxRestrictionsChanged(getCurrentRestrictions()); 173 } 174 175 /** 176 * Allow fragment to intercept back press and customize behavior. 177 */ onBackPressed()178 protected void onBackPressed() { 179 getFragmentHost().goBack(); 180 } 181 } 182