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