1 /* 2 * Copyright (C) 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 package com.android.wallpaper.picker; 17 18 import static android.view.View.GONE; 19 import static android.view.View.VISIBLE; 20 21 import android.annotation.MenuRes; 22 import android.content.Context; 23 import android.graphics.drawable.Drawable; 24 import android.os.Bundle; 25 import android.text.TextUtils; 26 import android.view.MenuItem; 27 import android.view.View; 28 import android.widget.TextView; 29 import android.widget.Toolbar; 30 import android.widget.Toolbar.OnMenuItemClickListener; 31 32 import androidx.annotation.Nullable; 33 34 import com.android.wallpaper.R; 35 import com.android.wallpaper.config.BaseFlags; 36 import com.android.wallpaper.util.ResourceUtils; 37 import com.android.wallpaper.widget.BottomActionBar; 38 39 import com.google.android.material.transition.MaterialSharedAxis; 40 41 /** 42 * Base class for Fragments that own a {@link Toolbar} widget and a {@link BottomActionBar}. 43 * 44 * A Fragment extending this class is expected to have a {@link Toolbar} in its root view, with id 45 * {@link R.id#toolbar}, which can optionally have a TextView with id custom_toolbar_title for 46 * the title. 47 * If the Bundle returned by {@link #createArguments(CharSequence)} is used as Arguments for this 48 * Fragment, the title provided to that method will be used as the Fragment's toolbar title, 49 * otherwise, the value returned by {@link #getDefaultTitle()} (default being {@code null}) will be 50 * used as title. 51 * 52 * @see #setArguments(Bundle) 53 * @see BottomActionBarFragment 54 */ 55 public abstract class AppbarFragment extends BottomActionBarFragment 56 implements OnMenuItemClickListener { 57 58 private static final String ARG_TITLE = "ToolbarFragment.title"; 59 private AppbarFragmentHost mHost; 60 private boolean mUpArrowEnabled; 61 62 /** 63 * Interface to be implemented by an Activity hosting a {@link AppbarFragment}. 64 */ 65 public interface AppbarFragmentHost { 66 /** 67 * Called when a up arrow had been pressed. 68 */ onUpArrowPressed()69 void onUpArrowPressed(); 70 71 /** 72 * Check if it supports up arrow. 73 */ isUpArrowSupported()74 boolean isUpArrowSupported(); 75 } 76 77 @Override onCreate(@ullable Bundle savedInstanceState)78 public void onCreate(@Nullable Bundle savedInstanceState) { 79 super.onCreate(savedInstanceState); 80 if (BaseFlags.get().isPageTransitionsFeatureEnabled(requireContext())) { 81 setEnterTransition(new MaterialSharedAxis(MaterialSharedAxis.X, /* forward */ true)); 82 setReturnTransition(new MaterialSharedAxis(MaterialSharedAxis.X, /* forward */ false)); 83 setExitTransition(new MaterialSharedAxis(MaterialSharedAxis.X, /* forward */ true)); 84 setReenterTransition(new MaterialSharedAxis(MaterialSharedAxis.X, /* forward */ false)); 85 } 86 } 87 88 @Override onAttach(Context context)89 public void onAttach(Context context) { 90 super.onAttach(context); 91 mHost = (AppbarFragmentHost) context; 92 } 93 94 /** 95 * Returns a newly created {@link Bundle} containing the given title as an argument. 96 * If set as a ToolbarFragment's arguments bundle, this will be used to set up the title of 97 * the Toolbar in {@link #setUpToolbar(View)} 98 */ createArguments(CharSequence title)99 protected static Bundle createArguments(CharSequence title) { 100 Bundle args = new Bundle(); 101 args.putCharSequence(ARG_TITLE, title); 102 return args; 103 } 104 105 protected Toolbar mToolbar; 106 private TextView mTitleView; 107 108 /** 109 * Configures a toolbar in the given rootView, with id {@code toolbar} and sets its title to 110 * the value in Arguments or {@link #getDefaultTitle()}. 111 * Default upArrow value is true. 112 */ setUpToolbar(View rootView)113 public void setUpToolbar(View rootView) { 114 setUpToolbar(rootView, /* upArrow= */ true); 115 } 116 117 /** 118 * Configures a toolbar in the given rootView, inflating the menu corresponding to the given id 119 * for the toolbar menu. 120 * 121 * @param rootView given root view. 122 * @param upArrow true to enable up arrow feature. 123 */ setUpToolbar(View rootView, boolean upArrow)124 protected void setUpToolbar(View rootView, boolean upArrow) { 125 mUpArrowEnabled = upArrow; 126 mToolbar = rootView.findViewById(getToolbarId()); 127 128 mTitleView = mToolbar.findViewById(R.id.custom_toolbar_title); 129 130 // Update toolbar and status bar color. 131 setToolbarColor(getToolbarColorId()); 132 133 CharSequence title; 134 if (getArguments() != null) { 135 title = getArguments().getCharSequence(ARG_TITLE, getDefaultTitle()); 136 } else { 137 title = getDefaultTitle(); 138 } 139 if (!TextUtils.isEmpty(title)) { 140 setTitle(title); 141 } 142 143 if (upArrow && mHost.isUpArrowSupported()) { 144 setUpUpArrow(); 145 } 146 } 147 148 /** 149 * Configures the menu in the toolbar. 150 * 151 * @param menuResId the resource id of the menu 152 */ setUpToolbarMenu(@enuRes int menuResId)153 public void setUpToolbarMenu(@MenuRes int menuResId) { 154 mToolbar.inflateMenu(menuResId); 155 mToolbar.setOnMenuItemClickListener(this); 156 } 157 setUpToolbarMenuClickListener(int menuItemResId, View.OnClickListener listener)158 protected void setUpToolbarMenuClickListener(int menuItemResId, View.OnClickListener listener) { 159 MenuItem menuItem = mToolbar.getMenu().findItem(menuItemResId); 160 menuItem.getActionView().setOnClickListener(listener); 161 } 162 getToolbarId()163 protected int getToolbarId() { 164 return R.id.toolbar; 165 } 166 getToolbarColorId()167 protected int getToolbarColorId() { 168 return R.color.toolbar_color; 169 } 170 getToolbarTextColor()171 protected int getToolbarTextColor() { 172 return ResourceUtils.getColorAttr(getActivity(), android.R.attr.textColorPrimary); 173 } 174 175 /** 176 * Set up arrow feature status to enabled or not. Enable it for updating 177 * onBottomActionBarReady() while initializing without toolbar setup. 178 * 179 * @param upArrow true to enable up arrow feature. 180 */ setUpArrowEnabled(boolean upArrow)181 public void setUpArrowEnabled(boolean upArrow) { 182 mUpArrowEnabled = upArrow; 183 } 184 setUpUpArrow()185 private void setUpUpArrow() { 186 Drawable backIcon = getResources().getDrawable(R.drawable.material_ic_arrow_back_black_24, 187 null).mutate(); 188 backIcon.setAutoMirrored(true); 189 backIcon.setTint(getToolbarTextColor()); 190 mToolbar.setNavigationIcon(backIcon); 191 mToolbar.setNavigationContentDescription(R.string.bottom_action_bar_back); 192 mToolbar.setNavigationOnClickListener(v -> mHost.onUpArrowPressed()); 193 } 194 195 /** 196 * Configures a toolbar in the given rootView, inflating the menu corresponding to the given id 197 * for the toolbar menu. 198 * Override {@link #onMenuItemClick(MenuItem)} to listen to item click events. 199 * @see #setUpToolbar(View) 200 */ setUpToolbar(View rootView, @MenuRes int menuResId)201 public void setUpToolbar(View rootView, @MenuRes int menuResId) { 202 setUpToolbar(rootView); 203 setUpToolbarMenu(menuResId); 204 } 205 setToolbarColor(int colorId)206 protected void setToolbarColor(int colorId) { 207 mToolbar.setBackgroundResource(colorId); 208 getActivity().getWindow().setStatusBarColor( 209 getActivity().getResources().getColor(colorId)); 210 } 211 212 /** 213 * Provides a title for this Fragment's toolbar to be used if none is found in 214 * {@link #getArguments()}. 215 * Default implementation returns {@code null}. 216 */ getDefaultTitle()217 public CharSequence getDefaultTitle() { 218 return null; 219 } 220 getAccessibilityTitle()221 protected String getAccessibilityTitle() { 222 return null; 223 } 224 setTitle(CharSequence title)225 protected void setTitle(CharSequence title) { 226 if (mToolbar == null) { 227 return; 228 } 229 if (mTitleView != null) { 230 mToolbar.setTitle(null); 231 mTitleView.setText(title); 232 mTitleView.setTextColor(getToolbarTextColor()); 233 } else { 234 mToolbar.setTitle(title); 235 mToolbar.setTitleTextColor(getToolbarTextColor()); 236 } 237 238 // Set Activity title to make TalkBack announce title after updating toolbar title. 239 if (getActivity() != null) { 240 String accessibilityTitle = getAccessibilityTitle(); 241 getActivity().setTitle(TextUtils.isEmpty(accessibilityTitle) ? title 242 : accessibilityTitle); 243 } 244 } 245 246 @Override onBottomActionBarReady(BottomActionBar bottomActionBar)247 protected void onBottomActionBarReady(BottomActionBar bottomActionBar) { 248 bottomActionBar.setBackButtonVisibility( 249 mUpArrowEnabled && mHost.isUpArrowSupported() ? GONE : VISIBLE); 250 super.onBottomActionBarReady(bottomActionBar); 251 } 252 253 @Override onMenuItemClick(MenuItem item)254 public boolean onMenuItemClick(MenuItem item) { 255 return false; 256 } 257 } 258