1 /*******************************************************************************
2  *      Copyright (C) 2014 Google Inc.
3  *      Licensed to The Android Open Source Project.
4  *
5  *      Licensed under the Apache License, Version 2.0 (the "License");
6  *      you may not use this file except in compliance with the License.
7  *      You may obtain a copy of the License at
8  *
9  *           http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *      Unless required by applicable law or agreed to in writing, software
12  *      distributed under the License is distributed on an "AS IS" BASIS,
13  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *      See the License for the specific language governing permissions and
15  *      limitations under the License.
16  *******************************************************************************/
17 
18 package com.android.mail.ui;
19 
20 import android.animation.Animator;
21 import android.animation.AnimatorListenerAdapter;
22 import android.content.Context;
23 import android.support.v7.widget.Toolbar;
24 import android.util.AttributeSet;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.widget.TextView;
28 
29 import com.android.mail.R;
30 import com.android.mail.analytics.Analytics;
31 import com.android.mail.providers.Account;
32 import com.android.mail.providers.AccountObserver;
33 import com.android.mail.utils.ViewUtils;
34 
35 /**
36  * Custom toolbar that supports a custom view so we can display our search icon wherever we want.
37  */
38 public class CustomViewToolbar extends Toolbar implements ViewMode.ModeChangeListener,
39         TwoPaneLayout.ConversationListLayoutListener {
40     private static final long FADE_ANIMATION_DURATION_MS = 150;
41 
42     private ControllableActivity mActivity;
43     private ActivityController mController;
44     private ViewMode mViewMode;
45     private AccountObserver mAccountObserver = new AccountObserver() {
46         @Override
47         public void onChanged(Account newAccount) {
48             setSearchButtonVisibility(newAccount);
49         }
50     };
51 
52     protected View mCustomView;
53     protected TextView mActionBarTitle;
54     protected View mSearchButton;
55 
CustomViewToolbar(Context context)56     public CustomViewToolbar(Context context) {
57         super(context);
58     }
59 
CustomViewToolbar(Context context, AttributeSet attrs)60     public CustomViewToolbar(Context context, AttributeSet attrs) {
61         super(context, attrs);
62     }
63 
setController(ControllableActivity activity, ActivityController controller, ViewMode viewMode)64     public void setController(ControllableActivity activity, ActivityController controller,
65             ViewMode viewMode) {
66         mActivity = activity;
67         mController = controller;
68         mViewMode = viewMode;
69         mViewMode.addListener(this);
70 
71         mAccountObserver.initialize(mActivity.getAccountController());
72     }
73 
74     @Override
onFinishInflate()75     protected void onFinishInflate() {
76         super.onFinishInflate();
77 
78         mCustomView = findViewById(R.id.actionbar_custom_view);
79         mActionBarTitle = (TextView) findViewById(R.id.actionbar_title);
80         mSearchButton = findViewById(R.id.actionbar_search_button);
81 
82         mSearchButton.setOnClickListener(new View.OnClickListener() {
83             @Override
84             public void onClick(View view) {
85                 // Since search is no longer a menu item, log the search "menu" event here.
86                 Analytics.getInstance().sendEvent(Analytics.EVENT_CATEGORY_MENU_ITEM,
87                         "search", "action_bar/" + mViewMode.getModeString(), 0);
88                 mController.startSearch();
89             }
90         });
91     }
92 
onDestroy()93     protected void onDestroy() {
94         mAccountObserver.unregisterAndDestroy();
95     }
96 
97     /**
98      * Sets the search button visibility based on the current account.
99      */
setSearchButtonVisibility()100     private void setSearchButtonVisibility() {
101         setSearchButtonVisibility(mActivity.getAccountController().getAccount());
102     }
103 
setSearchButtonVisibility(Account account)104     private void setSearchButtonVisibility(Account account) {
105         if (mSearchButton != null) {
106             final boolean visible = mController.shouldShowSearchMenuItem() &&
107                     account.supportsSearch();
108             mSearchButton.setVisibility(visible ? VISIBLE : INVISIBLE);
109         }
110     }
111 
112     @Override
onViewModeChanged(int newMode)113     public void onViewModeChanged(int newMode) {
114         setSearchButtonVisibility();
115     }
116 
117     @Override
onConversationListLayout(int xEnd, boolean drawerOpen)118     public void onConversationListLayout(int xEnd, boolean drawerOpen) {
119         if (drawerOpen) {
120             mSearchButton.animate()
121                     .alpha(0f)
122                     .setDuration(FADE_ANIMATION_DURATION_MS)
123                     .setListener(new AnimatorListenerAdapter() {
124                         @Override
125                         public void onAnimationEnd(Animator animation) {
126                             mSearchButton.setVisibility(INVISIBLE);
127                         }
128                     });
129         } else {
130             setSearchButtonVisibility();
131             // setListener(null) is necessary because the animator carries the previously set
132             // listener over, aka the listener for fade out.
133             if (mSearchButton.isShown()) {
134                 mSearchButton.animate()
135                         .alpha(1f)
136                         .setDuration(FADE_ANIMATION_DURATION_MS)
137                         .setListener(null);
138             }
139 
140             final int[] coords = new int[2];
141             mCustomView.getLocationInWindow(coords);
142             final int newWidth;
143             if (ViewUtils.isViewRtl(this)) {
144                 newWidth = coords[0] + mCustomView.getWidth() - xEnd;
145             } else {
146                 newWidth = xEnd - coords[0];
147             }
148 
149             // Only set the width if it's different than before so we avoid draw on layout pass.
150             if (mCustomView.getWidth() != newWidth) {
151                 final ViewGroup.LayoutParams params = mCustomView.getLayoutParams();
152                 params.width = newWidth;
153                 mCustomView.setLayoutParams(params);
154             }
155         }
156     }
157 
158     // OVERRIDE DEFAULT TOOLBAR TITLE FUNCTIONS SO THEY ARE RENDERED CORRECTLY.
159     // TODO: subtitles? we currently don't have any of those, but we will need to support them.
160 
161     @Override
setTitle(int resId)162     public void setTitle(int resId) {
163         setTitle(getResources().getString(resId));
164     }
165 
166     @Override
setTitle(CharSequence title)167     public void setTitle(CharSequence title) {
168         mActionBarTitle.setText(title);
169     }
170 
171     @Override
setTitleTextAppearance(Context context, int resId)172     public void setTitleTextAppearance(Context context, int resId) {
173         mActionBarTitle.setTextAppearance(context, resId);
174     }
175 
176     @Override
setTitleTextColor(int color)177     public void setTitleTextColor(int color) {
178         mActionBarTitle.setTextColor(color);
179     }
180 }
181