1 /* 2 * Copyright (C) 2017 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.launcher3.workprofile; 17 18 import android.content.Context; 19 import android.content.res.TypedArray; 20 import android.util.AttributeSet; 21 import android.widget.Button; 22 import android.widget.LinearLayout; 23 24 import androidx.annotation.NonNull; 25 import androidx.annotation.Nullable; 26 27 import com.android.launcher3.DeviceProfile; 28 import com.android.launcher3.R; 29 import com.android.launcher3.pageindicators.Direction; 30 import com.android.launcher3.pageindicators.PageIndicator; 31 import com.android.launcher3.views.ActivityContext; 32 33 import java.util.function.Consumer; 34 35 /** 36 * Supports two indicator colors, dedicated for personal and work tabs. 37 */ 38 public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageIndicator { 39 private final boolean mIsAlignOnIcon; 40 private OnActivePageChangedListener mOnActivePageChangedListener; 41 private int mLastActivePage = 0; 42 PersonalWorkSlidingTabStrip(@onNull Context context, @Nullable AttributeSet attrs)43 public PersonalWorkSlidingTabStrip(@NonNull Context context, @Nullable AttributeSet attrs) { 44 super(context, attrs); 45 TypedArray typedArray = context.obtainStyledAttributes(attrs, 46 R.styleable.PersonalWorkSlidingTabStrip); 47 mIsAlignOnIcon = typedArray.getBoolean( 48 R.styleable.PersonalWorkSlidingTabStrip_alignOnIcon, false); 49 typedArray.recycle(); 50 } 51 52 /** 53 * Highlights tab with index pos 54 */ updateTabTextColor(int pos)55 public void updateTabTextColor(int pos) { 56 for (int i = 0; i < getChildCount(); i++) { 57 Button tab = (Button) getChildAt(i); 58 tab.setSelected(i == pos); 59 } 60 } 61 62 @Override setScroll(int currentScroll, int totalScroll)63 public void setScroll(int currentScroll, int totalScroll) { 64 } 65 66 @Override setActiveMarker(int activePage)67 public void setActiveMarker(int activePage) { 68 updateTabTextColor(activePage); 69 if (mOnActivePageChangedListener != null && mLastActivePage != activePage) { 70 mOnActivePageChangedListener.onActivePageChanged(activePage); 71 } 72 mLastActivePage = activePage; 73 } 74 setOnActivePageChangedListener(OnActivePageChangedListener listener)75 public void setOnActivePageChangedListener(OnActivePageChangedListener listener) { 76 mOnActivePageChangedListener = listener; 77 } 78 79 @Override setMarkersCount(int numMarkers)80 public void setMarkersCount(int numMarkers) { 81 } 82 83 @Override setArrowClickListener(Consumer<Direction> listener)84 public void setArrowClickListener(Consumer<Direction> listener) { 85 // No-Op. All Apps doesn't need accessibility arrows for single click navigation. 86 } 87 88 @Override hasOverlappingRendering()89 public boolean hasOverlappingRendering() { 90 return false; 91 } 92 93 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)94 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 95 if (mIsAlignOnIcon) { 96 // If any padding is not specified, restrict the width to emulate padding 97 int size = MeasureSpec.getSize(widthMeasureSpec); 98 size = getTabWidth(getContext(), size); 99 widthMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); 100 } 101 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 102 } 103 104 /** 105 * Returns distance between left and right app icons 106 */ getTabWidth(Context context, int totalWidth)107 public static int getTabWidth(Context context, int totalWidth) { 108 DeviceProfile grid = ActivityContext.lookupContext(context).getDeviceProfile(); 109 int iconPadding = totalWidth / grid.numShownAllAppsColumns - grid.allAppsIconSizePx; 110 return totalWidth - iconPadding; 111 } 112 113 /** 114 * Interface definition for a callback to be invoked when an active page has been changed. 115 */ 116 public interface OnActivePageChangedListener { 117 /** Called when the active page has been changed. */ onActivePageChanged(int currentActivePage)118 void onActivePageChanged(int currentActivePage); 119 } 120 } 121