mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 11:18:21 +00:00
Extract common codes for personal / work profile tabs
These codes can be reused in the FullWidgetsSheet which we will be
adding tabs for personal / work profile.
Test: Set up work profile and then switch person / work profile tabs
in the AllAppsContainerView.
Bug: 179797520
Change-Id: Ib7eb1190e1384a664cbe3e34411c9362f1f6db03
This commit is contained in:
@@ -40,35 +40,7 @@
|
||||
|
||||
<include layout="@layout/floating_header_content" />
|
||||
|
||||
<com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
|
||||
android:id="@+id/tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/all_apps_header_tab_height"
|
||||
android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
|
||||
android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
|
||||
android:orientation="horizontal"
|
||||
style="@style/TextHeadline">
|
||||
|
||||
<Button
|
||||
android:id="@+id/tab_personal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:text="@string/all_apps_personal_tab"
|
||||
android:textColor="@color/all_apps_tab_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/tab_work"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:text="@string/all_apps_work_tab"
|
||||
android:textColor="@color/all_apps_tab_text"
|
||||
android:textSize="14sp" />
|
||||
</com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
|
||||
<include layout="@layout/personal_work_tabs" />
|
||||
</com.android.launcher3.allapps.FloatingHeaderView>
|
||||
|
||||
<include
|
||||
|
||||
47
res/layout/personal_work_tabs.xml
Normal file
47
res/layout/personal_work_tabs.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2021 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/all_apps_header_tab_height"
|
||||
android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
|
||||
android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
|
||||
android:orientation="horizontal"
|
||||
style="@style/TextHeadline">
|
||||
|
||||
<Button
|
||||
android:id="@+id/tab_personal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:text="@string/all_apps_personal_tab"
|
||||
android:textColor="@color/all_apps_tab_text"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/tab_work"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:text="@string/all_apps_work_tab"
|
||||
android:textColor="@color/all_apps_tab_text"
|
||||
android:textSize="14sp" />
|
||||
</com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip>
|
||||
@@ -67,7 +67,7 @@
|
||||
android:paddingTop="@dimen/all_apps_header_top_padding"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
|
||||
<com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
|
||||
android:id="@+id/tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/all_apps_header_tab_height"
|
||||
@@ -97,7 +97,7 @@
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@color/all_apps_tab_text"
|
||||
android:textSize="14sp" />
|
||||
</com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
|
||||
</com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip>
|
||||
</com.android.launcher3.allapps.FloatingHeaderView>
|
||||
|
||||
<com.android.launcher3.allapps.search.AppsSearchContainerLayout
|
||||
|
||||
@@ -67,12 +67,13 @@ import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.views.RecyclerViewFastScroller;
|
||||
import com.android.launcher3.views.SpringRelativeLayout;
|
||||
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
|
||||
|
||||
/**
|
||||
* The all apps view container.
|
||||
*/
|
||||
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
|
||||
Insettable, OnDeviceProfileChangeListener {
|
||||
Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener {
|
||||
|
||||
private static final float FLING_VELOCITY_MULTIPLIER = 135f;
|
||||
// Starts the springs after at least 55% of the animation has passed.
|
||||
@@ -434,7 +435,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
|
||||
.setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.MAIN));
|
||||
findViewById(R.id.tab_work)
|
||||
.setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.WORK));
|
||||
onTabChanged(mViewPager.getNextPage());
|
||||
onActivePageChanged(mViewPager.getNextPage());
|
||||
} else {
|
||||
mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
|
||||
mAH[AdapterHolder.WORK].recyclerView = null;
|
||||
@@ -483,7 +484,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
|
||||
if (showTabs) {
|
||||
mViewPager = (AllAppsPagedView) newView;
|
||||
mViewPager.initParentViews(this);
|
||||
mViewPager.getPageIndicator().setContainerView(this);
|
||||
mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
|
||||
} else {
|
||||
mViewPager = null;
|
||||
}
|
||||
@@ -493,14 +494,15 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
|
||||
return mViewPager != null ? mViewPager : findViewById(R.id.apps_list_view);
|
||||
}
|
||||
|
||||
public void onTabChanged(int pos) {
|
||||
mHeader.setMainActive(pos == 0);
|
||||
if (mAH[pos].recyclerView != null) {
|
||||
mAH[pos].recyclerView.bindFastScrollbar();
|
||||
@Override
|
||||
public void onActivePageChanged(int currentActivePage) {
|
||||
mHeader.setMainActive(currentActivePage == 0);
|
||||
if (mAH[currentActivePage].recyclerView != null) {
|
||||
mAH[currentActivePage].recyclerView.bindFastScrollbar();
|
||||
}
|
||||
reset(true /* animate */);
|
||||
if (mWorkModeSwitch != null) {
|
||||
mWorkModeSwitch.setWorkTabVisible(pos == AdapterHolder.WORK
|
||||
mWorkModeSwitch.setWorkTabVisible(currentActivePage == AdapterHolder.WORK
|
||||
&& mAllAppsStore.hasModelFlag(
|
||||
FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION));
|
||||
}
|
||||
|
||||
@@ -17,17 +17,17 @@ package com.android.launcher3.allapps;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.PagedView;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.workprofile.PersonalWorkPagedView;
|
||||
|
||||
public class AllAppsPagedView extends PagedView<PersonalWorkSlidingTabStrip> {
|
||||
|
||||
static final float START_DAMPING_TOUCH_SLOP_ANGLE = (float) Math.PI / 6;
|
||||
static final float MAX_SWIPE_ANGLE = (float) Math.PI / 3;
|
||||
static final float TOUCH_SLOP_DAMPING_FACTOR = 4;
|
||||
/**
|
||||
* A {@link PagedView} for showing different views for the personal and work profile respectively
|
||||
* in the {@link AllAppsContainerView}.
|
||||
*/
|
||||
public class AllAppsPagedView extends PersonalWorkPagedView {
|
||||
|
||||
public AllAppsPagedView(Context context) {
|
||||
this(context, null);
|
||||
@@ -44,52 +44,4 @@ public class AllAppsPagedView extends PagedView<PersonalWorkSlidingTabStrip> {
|
||||
R.dimen.all_apps_header_top_padding);
|
||||
setPadding(0, topPadding, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCurrentPageDescription() {
|
||||
// Not necessary, tab-bar already has two tabs with their own descriptions.
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
|
||||
super.onScrollChanged(l, t, oldl, oldt);
|
||||
mPageIndicator.setScroll(l, mMaxScroll);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void determineScrollingStart(MotionEvent ev) {
|
||||
float absDeltaX = Math.abs(ev.getX() - getDownMotionX());
|
||||
float absDeltaY = Math.abs(ev.getY() - getDownMotionY());
|
||||
|
||||
if (Float.compare(absDeltaX, 0f) == 0) return;
|
||||
|
||||
float slope = absDeltaY / absDeltaX;
|
||||
float theta = (float) Math.atan(slope);
|
||||
|
||||
if (absDeltaX > mTouchSlop || absDeltaY > mTouchSlop) {
|
||||
cancelCurrentPageLongPress();
|
||||
}
|
||||
|
||||
if (theta > MAX_SWIPE_ANGLE) {
|
||||
return;
|
||||
} else if (theta > START_DAMPING_TOUCH_SLOP_ANGLE) {
|
||||
theta -= START_DAMPING_TOUCH_SLOP_ANGLE;
|
||||
float extraRatio = (float)
|
||||
Math.sqrt((theta / (MAX_SWIPE_ANGLE - START_DAMPING_TOUCH_SLOP_ANGLE)));
|
||||
super.determineScrollingStart(ev, 1 + TOUCH_SLOP_DAMPING_FACTOR * extraRatio);
|
||||
} else {
|
||||
super.determineScrollingStart(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canScroll(float absVScroll, float absHScroll) {
|
||||
return (absHScroll > absVScroll) && super.canScroll(absVScroll, absHScroll);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,17 +87,18 @@ public class LauncherAllAppsContainerView extends AllAppsContainerView {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabChanged(int pos) {
|
||||
super.onTabChanged(pos);
|
||||
public void onActivePageChanged(int currentActivePage) {
|
||||
super.onActivePageChanged(currentActivePage);
|
||||
if (mUsingTabs) {
|
||||
// Log tab switches only when the launcher is in AllApps state
|
||||
if (mLauncher.getStateManager().getCurrentStableState() == LauncherState.ALL_APPS) {
|
||||
mLauncher.getStatsLogManager().logger()
|
||||
.log(pos == AdapterHolder.WORK ? LAUNCHER_ALLAPPS_SWITCHED_TO_WORK_TAB
|
||||
.log(currentActivePage == AdapterHolder.WORK
|
||||
? LAUNCHER_ALLAPPS_SWITCHED_TO_WORK_TAB
|
||||
: LAUNCHER_ALLAPPS_SWITCHED_TO_MAIN_TAB);
|
||||
}
|
||||
|
||||
if (pos == AdapterHolder.WORK) {
|
||||
if (currentActivePage == AdapterHolder.WORK) {
|
||||
WorkEduView.showWorkEduIfNeeded(mLauncher);
|
||||
} else {
|
||||
mWorkTabListener = WorkEduView.showEduFlowIfNeeded(mLauncher, mWorkTabListener);
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.workprofile;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.PagedView;
|
||||
|
||||
/**
|
||||
* A {@link PagedView} for showing different views for the personal and work profile respectively.
|
||||
*/
|
||||
public class PersonalWorkPagedView extends PagedView<PersonalWorkSlidingTabStrip> {
|
||||
|
||||
static final float START_DAMPING_TOUCH_SLOP_ANGLE = (float) Math.PI / 6;
|
||||
static final float MAX_SWIPE_ANGLE = (float) Math.PI / 3;
|
||||
static final float TOUCH_SLOP_DAMPING_FACTOR = 4;
|
||||
|
||||
public PersonalWorkPagedView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public PersonalWorkPagedView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public PersonalWorkPagedView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCurrentPageDescription() {
|
||||
// Not necessary, tab-bar already has two tabs with their own descriptions.
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
|
||||
super.onScrollChanged(l, t, oldl, oldt);
|
||||
mPageIndicator.setScroll(l, mMaxScroll);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void determineScrollingStart(MotionEvent ev) {
|
||||
float absDeltaX = Math.abs(ev.getX() - getDownMotionX());
|
||||
float absDeltaY = Math.abs(ev.getY() - getDownMotionY());
|
||||
|
||||
if (Float.compare(absDeltaX, 0f) == 0) return;
|
||||
|
||||
float slope = absDeltaY / absDeltaX;
|
||||
float theta = (float) Math.atan(slope);
|
||||
|
||||
if (absDeltaX > mTouchSlop || absDeltaY > mTouchSlop) {
|
||||
cancelCurrentPageLongPress();
|
||||
}
|
||||
|
||||
if (theta > MAX_SWIPE_ANGLE) {
|
||||
return;
|
||||
} else if (theta > START_DAMPING_TOUCH_SLOP_ANGLE) {
|
||||
theta -= START_DAMPING_TOUCH_SLOP_ANGLE;
|
||||
float extraRatio = (float)
|
||||
Math.sqrt((theta / (MAX_SWIPE_ANGLE - START_DAMPING_TOUCH_SLOP_ANGLE)));
|
||||
super.determineScrollingStart(ev, 1 + TOUCH_SLOP_DAMPING_FACTOR * extraRatio);
|
||||
} else {
|
||||
super.determineScrollingStart(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canScroll(float absVScroll, float absHScroll) {
|
||||
return (absHScroll > absVScroll) && super.canScroll(absVScroll, absHScroll);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.allapps;
|
||||
package com.android.launcher3.workprofile;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
@@ -35,9 +35,6 @@ import com.android.launcher3.util.Themes;
|
||||
* Supports two indicator colors, dedicated for personal and work tabs.
|
||||
*/
|
||||
public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageIndicator {
|
||||
private static final int POSITION_PERSONAL = 0;
|
||||
private static final int POSITION_WORK = 1;
|
||||
|
||||
private final Paint mSelectedIndicatorPaint;
|
||||
private final Paint mDividerPaint;
|
||||
|
||||
@@ -47,7 +44,7 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd
|
||||
private float mScrollOffset;
|
||||
private int mSelectedPosition = 0;
|
||||
|
||||
private AllAppsContainerView mContainerView;
|
||||
private OnActivePageChangedListener mOnActivePageChangedListener;
|
||||
private int mLastActivePage = 0;
|
||||
private boolean mIsRtl;
|
||||
|
||||
@@ -123,7 +120,7 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd
|
||||
float y = getHeight() - mDividerPaint.getStrokeWidth();
|
||||
canvas.drawLine(getPaddingLeft(), y, getWidth() - getPaddingRight(), y, mDividerPaint);
|
||||
canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight,
|
||||
mIndicatorRight, getHeight(), mSelectedIndicatorPaint);
|
||||
mIndicatorRight, getHeight(), mSelectedIndicatorPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,15 +132,15 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd
|
||||
@Override
|
||||
public void setActiveMarker(int activePage) {
|
||||
updateTabTextColor(activePage);
|
||||
if (mContainerView != null && mLastActivePage != activePage) {
|
||||
if (mOnActivePageChangedListener != null && mLastActivePage != activePage) {
|
||||
updateIndicatorPosition(activePage);
|
||||
mContainerView.onTabChanged(activePage);
|
||||
mOnActivePageChangedListener.onActivePageChanged(activePage);
|
||||
}
|
||||
mLastActivePage = activePage;
|
||||
}
|
||||
|
||||
public void setContainerView(AllAppsContainerView containerView) {
|
||||
mContainerView = containerView;
|
||||
public void setOnActivePageChangedListener(OnActivePageChangedListener listener) {
|
||||
mOnActivePageChangedListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,4 +150,12 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when an active page has been changed.
|
||||
*/
|
||||
public interface OnActivePageChangedListener {
|
||||
/** Called when the active page has been changed. */
|
||||
void onActivePageChanged(int currentActivePage);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user