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 17 package com.android.dialer.main.impl.bottomnav; 18 19 import android.content.Context; 20 import android.support.annotation.IntDef; 21 import android.support.annotation.Nullable; 22 import android.util.AttributeSet; 23 import android.view.View; 24 import android.widget.LinearLayout; 25 import com.android.dialer.common.Assert; 26 import com.android.dialer.common.LogUtil; 27 import com.android.dialer.logging.DialerImpression; 28 import com.android.dialer.logging.Logger; 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.util.ArrayList; 32 import java.util.List; 33 34 /** Dialer Bottom Nav Bar for {@link MainActivity}. */ 35 public final class BottomNavBar extends LinearLayout { 36 37 /** Index for each tab in the bottom nav. */ 38 @Retention(RetentionPolicy.SOURCE) 39 @IntDef({ 40 TabIndex.SPEED_DIAL, 41 TabIndex.CALL_LOG, 42 TabIndex.CONTACTS, 43 TabIndex.VOICEMAIL, 44 }) 45 public @interface TabIndex { 46 int SPEED_DIAL = 0; 47 int CALL_LOG = 1; 48 int CONTACTS = 2; 49 int VOICEMAIL = 3; 50 } 51 52 private final List<OnBottomNavTabSelectedListener> listeners = new ArrayList<>(); 53 54 private BottomNavItem speedDial; 55 private BottomNavItem callLog; 56 private BottomNavItem contacts; 57 private BottomNavItem voicemail; 58 private @TabIndex int selectedTab; 59 BottomNavBar(Context context, @Nullable AttributeSet attrs)60 public BottomNavBar(Context context, @Nullable AttributeSet attrs) { 61 super(context, attrs); 62 } 63 64 @Override onFinishInflate()65 protected void onFinishInflate() { 66 super.onFinishInflate(); 67 speedDial = findViewById(R.id.speed_dial_tab); 68 callLog = findViewById(R.id.call_log_tab); 69 contacts = findViewById(R.id.contacts_tab); 70 voicemail = findViewById(R.id.voicemail_tab); 71 72 speedDial.setup(R.string.tab_title_speed_dial, R.drawable.quantum_ic_star_vd_theme_24); 73 callLog.setup(R.string.tab_title_call_history, R.drawable.quantum_ic_access_time_vd_theme_24); 74 contacts.setup(R.string.tab_title_contacts, R.drawable.quantum_ic_people_vd_theme_24); 75 voicemail.setup(R.string.tab_title_voicemail, R.drawable.quantum_ic_voicemail_vd_theme_24); 76 77 speedDial.setOnClickListener( 78 v -> { 79 if (selectedTab != TabIndex.SPEED_DIAL) { 80 Logger.get(getContext()) 81 .logImpression(DialerImpression.Type.MAIN_SWITCH_TAB_TO_FAVORITE); 82 } 83 selectTab(TabIndex.SPEED_DIAL); 84 }); 85 callLog.setOnClickListener( 86 v -> { 87 if (selectedTab != TabIndex.CALL_LOG) { 88 Logger.get(getContext()) 89 .logImpression(DialerImpression.Type.MAIN_SWITCH_TAB_TO_CALL_LOG); 90 } 91 selectTab(TabIndex.CALL_LOG); 92 }); 93 contacts.setOnClickListener( 94 v -> { 95 if (selectedTab != TabIndex.CONTACTS) { 96 Logger.get(getContext()) 97 .logImpression(DialerImpression.Type.MAIN_SWITCH_TAB_TO_CONTACTS); 98 } 99 selectTab(TabIndex.CONTACTS); 100 }); 101 voicemail.setOnClickListener( 102 v -> { 103 if (selectedTab != TabIndex.VOICEMAIL) { 104 Logger.get(getContext()) 105 .logImpression(DialerImpression.Type.MAIN_SWITCH_TAB_TO_VOICEMAIL); 106 } 107 selectTab(TabIndex.VOICEMAIL); 108 }); 109 } 110 setSelected(View view)111 private void setSelected(View view) { 112 speedDial.setSelected(view == speedDial); 113 callLog.setSelected(view == callLog); 114 contacts.setSelected(view == contacts); 115 voicemail.setSelected(view == voicemail); 116 } 117 118 /** 119 * Select tab for uesr and non-user click. 120 * 121 * @param tab {@link TabIndex} 122 */ selectTab(@abIndex int tab)123 public void selectTab(@TabIndex int tab) { 124 if (tab == TabIndex.SPEED_DIAL) { 125 selectedTab = TabIndex.SPEED_DIAL; 126 setSelected(speedDial); 127 } else if (tab == TabIndex.CALL_LOG) { 128 selectedTab = TabIndex.CALL_LOG; 129 setSelected(callLog); 130 } else if (tab == TabIndex.CONTACTS) { 131 selectedTab = TabIndex.CONTACTS; 132 setSelected(contacts); 133 } else if (tab == TabIndex.VOICEMAIL) { 134 selectedTab = TabIndex.VOICEMAIL; 135 setSelected(voicemail); 136 } else { 137 throw new IllegalStateException("Invalid tab: " + tab); 138 } 139 140 updateListeners(selectedTab); 141 } 142 143 /** 144 * Displays or hides the voicemail tab. 145 * 146 * <p>In the event that the voicemail tab was earlier visible but is now no longer visible, we 147 * move to the speed dial tab. 148 * 149 * @param showTab whether to hide or show the voicemail 150 */ showVoicemail(boolean showTab)151 public void showVoicemail(boolean showTab) { 152 LogUtil.i("OldMainActivityPeer.showVoicemail", "showing Tab:%b", showTab); 153 int voicemailpreviousVisibility = voicemail.getVisibility(); 154 voicemail.setVisibility(showTab ? View.VISIBLE : View.GONE); 155 int voicemailcurrentVisibility = voicemail.getVisibility(); 156 157 if (voicemailpreviousVisibility != voicemailcurrentVisibility 158 && voicemailpreviousVisibility == View.VISIBLE 159 && getSelectedTab() == TabIndex.VOICEMAIL) { 160 LogUtil.i("OldMainActivityPeer.showVoicemail", "hid VM tab and moved to speed dial tab"); 161 selectTab(TabIndex.SPEED_DIAL); 162 } 163 } 164 setNotificationCount(@abIndex int tab, int count)165 public void setNotificationCount(@TabIndex int tab, int count) { 166 if (tab == TabIndex.SPEED_DIAL) { 167 speedDial.setNotificationCount(count); 168 } else if (tab == TabIndex.CALL_LOG) { 169 callLog.setNotificationCount(count); 170 } else if (tab == TabIndex.CONTACTS) { 171 contacts.setNotificationCount(count); 172 } else if (tab == TabIndex.VOICEMAIL) { 173 voicemail.setNotificationCount(count); 174 } else { 175 throw new IllegalStateException("Invalid tab: " + tab); 176 } 177 } 178 addOnTabSelectedListener(OnBottomNavTabSelectedListener listener)179 public void addOnTabSelectedListener(OnBottomNavTabSelectedListener listener) { 180 listeners.add(listener); 181 } 182 updateListeners(@abIndex int tabIndex)183 private void updateListeners(@TabIndex int tabIndex) { 184 for (OnBottomNavTabSelectedListener listener : listeners) { 185 switch (tabIndex) { 186 case TabIndex.SPEED_DIAL: 187 listener.onSpeedDialSelected(); 188 break; 189 case TabIndex.CALL_LOG: 190 listener.onCallLogSelected(); 191 break; 192 case TabIndex.CONTACTS: 193 listener.onContactsSelected(); 194 break; 195 case TabIndex.VOICEMAIL: 196 listener.onVoicemailSelected(); 197 break; 198 default: 199 throw Assert.createIllegalStateFailException("Invalid tab: " + tabIndex); 200 } 201 } 202 } 203 204 @TabIndex getSelectedTab()205 public int getSelectedTab() { 206 return selectedTab; 207 } 208 209 /** Listener for bottom nav tab's on click events. */ 210 public interface OnBottomNavTabSelectedListener { 211 212 /** Speed dial tab was clicked. */ onSpeedDialSelected()213 void onSpeedDialSelected(); 214 215 /** Call Log tab was clicked. */ onCallLogSelected()216 void onCallLogSelected(); 217 218 /** Contacts tab was clicked. */ onContactsSelected()219 void onContactsSelected(); 220 221 /** Voicemail tab was clicked. */ onVoicemailSelected()222 void onVoicemailSelected(); 223 } 224 } 225