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