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