1 /* 2 * Copyright (C) 2022 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 package com.android.wallpaper.widget; 17 18 import android.content.Context; 19 import android.content.res.TypedArray; 20 import android.util.AttributeSet; 21 import android.view.LayoutInflater; 22 import android.widget.FrameLayout; 23 import android.widget.TextView; 24 25 import androidx.annotation.IntDef; 26 import androidx.annotation.NonNull; 27 import androidx.annotation.Nullable; 28 29 import com.android.wallpaper.R; 30 import com.android.wallpaper.util.SystemColors; 31 32 /** 33 * Custom layout for duo tabs. 34 */ 35 public final class DuoTabs extends FrameLayout { 36 37 public static final int TAB_PRIMARY = 0; 38 public static final int TAB_SECONDARY = 1; 39 40 @IntDef({TAB_PRIMARY, TAB_SECONDARY}) 41 public @interface Tab { 42 } 43 44 public interface OnTabSelectedListener { onTabSelected(@ab int tab)45 void onTabSelected(@Tab int tab); 46 } 47 48 private OnTabSelectedListener mOnTabSelectedListener; 49 @Nullable private final FrameLayout mPrimaryTabContainer; 50 @Nullable private final FrameLayout mSecondaryTabContainer; 51 private final TextView mPrimaryTabText; 52 private final TextView mSecondaryTabText; 53 54 @Tab private int mCurrentOverlayTab; 55 56 private final int mSelectedTabDrawable; 57 58 private final int mNonSelectedTabDrawable; 59 60 private final int mSelectedTabTextColor; 61 62 private final int mNonSelectedTabTextColor; 63 64 private final boolean mShouldUseShortTabs; 65 DuoTabs(@onNull Context context, @Nullable AttributeSet attrs)66 public DuoTabs(@NonNull Context context, @Nullable AttributeSet attrs) { 67 super(context, attrs); 68 69 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DuoTabs, 0, 0); 70 mShouldUseShortTabs = a.getBoolean(R.styleable.DuoTabs_should_use_short_tabs, false); 71 mSelectedTabDrawable = a.getResourceId(R.styleable.DuoTabs_selected_tab_drawable, 72 R.drawable.duo_tabs_preview_button_indicator_background); 73 mNonSelectedTabDrawable = a.getResourceId(R.styleable.DuoTabs_non_selected_tab_drawable, 74 R.drawable.duo_tabs_preview_button_background); 75 mSelectedTabTextColor = a.getColor(R.styleable.DuoTabs_selected_tab_text_color, 76 getResources().getColor(R.color.text_color_on_accent)); 77 mNonSelectedTabTextColor = a.getColor(R.styleable.DuoTabs_non_selected_tab_text_color, 78 SystemColors.getColor(getContext(), android.R.attr.textColorPrimary)); 79 a.recycle(); 80 81 LayoutInflater.from(context).inflate( 82 mShouldUseShortTabs ? R.layout.duo_tabs_short : R.layout.duo_tabs, 83 this, 84 true); 85 86 mPrimaryTabText = findViewById(R.id.tab_primary); 87 mSecondaryTabText = findViewById(R.id.tab_secondary); 88 mPrimaryTabContainer = mShouldUseShortTabs ? findViewById(R.id.tab_primary_container) 89 : null; 90 mSecondaryTabContainer = mShouldUseShortTabs ? findViewById(R.id.tab_secondary_container) 91 : null; 92 if (mShouldUseShortTabs && mPrimaryTabContainer != null && mSecondaryTabContainer != null) { 93 mPrimaryTabContainer.setOnClickListener(v -> selectTab(TAB_PRIMARY)); 94 mSecondaryTabContainer.setOnClickListener(v -> selectTab(TAB_SECONDARY)); 95 } else { 96 mPrimaryTabText.setOnClickListener(v -> selectTab(TAB_PRIMARY)); 97 mSecondaryTabText.setOnClickListener(v -> selectTab(TAB_SECONDARY)); 98 } 99 } 100 setTabText(String primaryTabText, String secondaryTabText)101 public void setTabText(String primaryTabText, String secondaryTabText) { 102 mPrimaryTabText.setText(primaryTabText); 103 mSecondaryTabText.setText(secondaryTabText); 104 } 105 selectTab(@ab int tab)106 public void selectTab(@Tab int tab) { 107 updateTabIndicator(tab); 108 if (mOnTabSelectedListener != null) { 109 mOnTabSelectedListener.onTabSelected(tab); 110 } 111 mCurrentOverlayTab = tab; 112 } 113 setOnTabSelectedListener( OnTabSelectedListener onTabSelectedListener)114 public void setOnTabSelectedListener( 115 OnTabSelectedListener onTabSelectedListener) { 116 mOnTabSelectedListener = onTabSelectedListener; 117 } 118 119 /** 120 * Update the background color in case the context theme changes. 121 */ updateBackgroundColor()122 public void updateBackgroundColor() { 123 mPrimaryTabText.setBackground(null); 124 mSecondaryTabText.setBackground(null); 125 updateTabIndicator(mCurrentOverlayTab); 126 } 127 updateTabIndicator(@ab int tab)128 private void updateTabIndicator(@Tab int tab) { 129 mPrimaryTabText.setBackgroundResource( 130 tab == TAB_PRIMARY 131 ? mSelectedTabDrawable 132 : mNonSelectedTabDrawable); 133 mPrimaryTabText.setTextColor( 134 tab == TAB_PRIMARY 135 ? mSelectedTabTextColor 136 : mNonSelectedTabTextColor); 137 // Set selected for talkback 138 if (mShouldUseShortTabs && mPrimaryTabContainer != null) { 139 mPrimaryTabContainer.setSelected(tab == TAB_PRIMARY); 140 } else { 141 mPrimaryTabText.setSelected(tab == TAB_PRIMARY); 142 } 143 mSecondaryTabText.setBackgroundResource( 144 tab == TAB_SECONDARY 145 ? mSelectedTabDrawable 146 : mNonSelectedTabDrawable); 147 mSecondaryTabText.setTextColor( 148 tab == TAB_SECONDARY 149 ? mSelectedTabTextColor 150 : mNonSelectedTabTextColor); 151 // Set selected for talkback 152 if (mShouldUseShortTabs && mSecondaryTabContainer != null) { 153 mSecondaryTabContainer.setSelected(tab == TAB_SECONDARY); 154 } else { 155 mSecondaryTabText.setSelected(tab == TAB_SECONDARY); 156 } 157 } 158 getSelectedTab()159 public @Tab int getSelectedTab() { 160 return mCurrentOverlayTab; 161 } 162 } 163