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 androidx.appcompat.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