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