1 /* 2 * Copyright (C) 2019 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.car.dialer.ui; 18 19 import android.content.Context; 20 import android.graphics.drawable.Drawable; 21 22 import androidx.annotation.Nullable; 23 import androidx.annotation.StringDef; 24 import androidx.fragment.app.Fragment; 25 import androidx.fragment.app.FragmentManager; 26 27 import com.android.car.dialer.R; 28 import com.android.car.dialer.ui.calllog.CallHistoryFragment; 29 import com.android.car.dialer.ui.contact.ContactListFragment; 30 import com.android.car.dialer.ui.dialpad.DialpadFragment; 31 import com.android.car.dialer.ui.favorite.FavoriteFragment; 32 import com.android.car.ui.toolbar.TabLayout; 33 34 import com.google.common.collect.ImmutableMap; 35 36 import java.util.HashMap; 37 import java.util.Map; 38 39 /** 40 * Tab presenting fragments. 41 */ 42 public class TelecomPageTab extends TabLayout.Tab { 43 44 /** 45 * Note: the strings must be consist with the items in string array tabs_config 46 */ 47 @StringDef({ 48 TelecomPageTab.Page.FAVORITES, 49 TelecomPageTab.Page.CALL_HISTORY, 50 TelecomPageTab.Page.CONTACTS, 51 TelecomPageTab.Page.DIAL_PAD 52 }) 53 public @interface Page { 54 String FAVORITES = "FAVORITE"; 55 String CALL_HISTORY = "CALL_HISTORY"; 56 String CONTACTS = "CONTACTS"; 57 String DIAL_PAD = "DIAL_PAD"; 58 } 59 60 private final Factory mFactory; 61 private Fragment mFragment; 62 private String mFragmentTag; 63 private boolean mWasFragmentRestored; 64 TelecomPageTab(@ullable Drawable icon, @Nullable CharSequence text, Factory factory)65 private TelecomPageTab(@Nullable Drawable icon, @Nullable CharSequence text, Factory factory) { 66 super(icon, text); 67 mFactory = factory; 68 } 69 70 /** 71 * Either restore fragment from saved state or create new instance. 72 */ initFragment(FragmentManager fragmentManager, @Page String page)73 private void initFragment(FragmentManager fragmentManager, @Page String page) { 74 mFragmentTag = makeFragmentTag(page); 75 mFragment = fragmentManager.findFragmentByTag(mFragmentTag); 76 if (mFragment == null) { 77 mFragment = mFactory.createFragment(page); 78 mWasFragmentRestored = false; 79 return; 80 } 81 mWasFragmentRestored = true; 82 } 83 84 /** 85 * Returns true if the fragment for this tab is restored from a saved state. 86 */ wasFragmentRestored()87 public boolean wasFragmentRestored() { 88 return mWasFragmentRestored; 89 } 90 91 /** 92 * Returns the fragment for this tab. 93 */ getFragment()94 public Fragment getFragment() { 95 return mFragment; 96 } 97 98 /** 99 * Returns the fragment tag for this tab. 100 */ getFragmentTag()101 public String getFragmentTag() { 102 return mFragmentTag; 103 } 104 makeFragmentTag(@age String page)105 private String makeFragmentTag(@Page String page) { 106 return String.format("%s:%s", getClass().getSimpleName(), page); 107 } 108 109 /** 110 * Responsible for creating the top tab items and their fragments. 111 */ 112 public static class Factory { 113 114 private static final ImmutableMap<String, Integer> TAB_LABELS = 115 ImmutableMap.<String, Integer>builder() 116 .put(Page.FAVORITES, R.string.favorites_title) 117 .put(Page.CALL_HISTORY, R.string.call_history_title) 118 .put(Page.CONTACTS, R.string.contacts_title) 119 .put(Page.DIAL_PAD, R.string.dialpad_title) 120 .build(); 121 122 private static final ImmutableMap<String, Integer> TAB_ICONS = 123 ImmutableMap.<String, Integer>builder() 124 .put(Page.FAVORITES, R.drawable.ic_favorite) 125 .put(Page.CALL_HISTORY, R.drawable.ic_history) 126 .put(Page.CONTACTS, R.drawable.ic_contact) 127 .put(Page.DIAL_PAD, R.drawable.ic_dialpad) 128 .build(); 129 130 private final FragmentManager mFragmentManager; 131 private final Map<String, Integer> mTabPageIndexMap; 132 private final String[] mTabs; 133 Factory(Context context, FragmentManager fragmentManager)134 public Factory(Context context, FragmentManager fragmentManager) { 135 mFragmentManager = fragmentManager; 136 137 mTabs = context.getResources().getStringArray(R.array.tabs_config); 138 139 mTabPageIndexMap = new HashMap<>(); 140 for (int i = 0; i < getTabCount(); i++) { 141 mTabPageIndexMap.put(mTabs[i], i); 142 } 143 } 144 createFragment(@age String page)145 private Fragment createFragment(@Page String page) { 146 switch (page) { 147 case Page.FAVORITES: 148 return FavoriteFragment.newInstance(); 149 case Page.CALL_HISTORY: 150 return CallHistoryFragment.newInstance(); 151 case Page.CONTACTS: 152 return ContactListFragment.newInstance(); 153 case Page.DIAL_PAD: 154 return DialpadFragment.newPlaceCallDialpad(); 155 default: 156 throw new UnsupportedOperationException("Tab is not supported."); 157 } 158 } 159 160 /** 161 * Create the tab for the given {@param tabIndex} 162 */ createTab(Context context, int tabIndex)163 public TelecomPageTab createTab(Context context, int tabIndex) { 164 String page = mTabs[tabIndex]; 165 TelecomPageTab telecomPageTab = new TelecomPageTab( 166 context.getDrawable(TAB_ICONS.get(page)), 167 context.getString(TAB_LABELS.get(page)), this); 168 telecomPageTab.initFragment(mFragmentManager, page); 169 return telecomPageTab; 170 } 171 getTabCount()172 public int getTabCount() { 173 return mTabs.length; 174 } 175 176 /** 177 * Returns the index for the given {@param page} 178 */ getTabIndex(@age String page)179 public int getTabIndex(@Page String page) { 180 return mTabPageIndexMap.containsKey(page) ? mTabPageIndexMap.get(page) : -1; 181 } 182 } 183 } 184