Merge "[Search][Motion] Introduce header protection in AllApps" into sc-dev

This commit is contained in:
Samuel Fufa
2021-05-07 17:59:08 +00:00
committed by Android (Google) Code Review
6 changed files with 127 additions and 9 deletions
+2 -1
View File
@@ -92,7 +92,8 @@
<dimen name="all_apps_background_canvas_width">700dp</dimen>
<dimen name="all_apps_background_canvas_height">475dp</dimen>
<dimen name="all_apps_header_pill_height">50dp</dimen>
<dimen name="all_apps_header_pill_corner_radius">50dp</dimen>
<dimen name="all_apps_header_pill_corner_radius">48dp</dimen>
<dimen name="all_apps_header_tab_height">48dp</dimen>
<dimen name="all_apps_tabs_indicator_height">2dp</dimen>
<dimen name="all_apps_header_top_padding">36dp</dimen>
<dimen name="all_apps_work_profile_tab_footer_top_padding">16dp</dimen>
+1 -1
View File
@@ -1192,7 +1192,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
// Setup the drag controller (drop targets have to be added in reverse order in priority)
mDropTargetBar.setup(mDragController);
mAllAppsController.setupViews(mAppsView);
mAllAppsController.setupViews(mScrimView, mAppsView);
}
/**
@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
@@ -44,6 +45,7 @@ import android.view.WindowInsets;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.graphics.ColorUtils;
import androidx.core.os.BuildCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -66,6 +68,7 @@ import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.RecyclerViewFastScroller;
import com.android.launcher3.views.ScrimView;
import com.android.launcher3.views.SpringRelativeLayout;
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
@@ -73,13 +76,16 @@ import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePag
* The all apps view container.
*/
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener {
Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener,
ScrimView.ScrimDrawingController {
private static final float FLING_VELOCITY_MULTIPLIER = 1000f;
// Starts the springs after at least 25% of the animation has passed.
private static final float FLING_ANIMATION_THRESHOLD = 0.25f;
private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
protected final BaseDraggingActivity mLauncher;
protected final AdapterHolder[] mAH;
private final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser(Process.myUserHandle());
@@ -93,7 +99,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
private View mSearchContainer;
private AllAppsPagedView mViewPager;
private FloatingHeaderView mHeader;
protected FloatingHeaderView mHeader;
private WorkModeSwitch mWorkModeSwitch;
@@ -107,7 +113,14 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
private Rect mInsets = new Rect();
SearchAdapterProvider mSearchAdapterProvider;
private SearchAdapterProvider mSearchAdapterProvider;
private final int mHeaderTopPadding;
private final int mScrimColor;
private final int mHeaderProtectionColor;
private final float mHeaderThreshold;
private ScrimView mScrimView;
private int mHeaderColor;
public AllAppsContainerView(Context context) {
this(context, null);
@@ -121,8 +134,19 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
super(context, attrs, defStyleAttr);
mLauncher = BaseDraggingActivity.fromContext(context);
mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
mHeaderThreshold = getResources().getDimensionPixelSize(
R.dimen.dynamic_grid_cell_border_spacing);
mHeaderTopPadding = context.getResources()
.getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
int accentColor = Themes.getColorAccent(getContext());
mHeaderProtectionColor = ColorUtils.blendARGB(mScrimColor, accentColor, .3f);
mLauncher.addOnDeviceProfileChangeListener(this);
mSearchAdapterProvider = mLauncher.createSearchAdapterProvider(this);
mSearchQueryBuilder = new SpannableStringBuilder();
Selection.setSelection(mSearchQueryBuilder, 0);
@@ -300,6 +324,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
}
// Reset the search bar and base recycler view after transitioning home
mSearchUiManager.resetSearch();
updateHeaderScroll(0);
}
@Override
@@ -625,6 +650,26 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
outRect.offset(0, (int) getTranslationY());
}
@Override
public void setTranslationY(float translationY) {
super.setTranslationY(translationY);
invalidateHeader();
}
public void setScrimView(ScrimView scrimView) {
mScrimView = scrimView;
}
@Override
public void drawOnScrim(Canvas canvas) {
mHeaderPaint.setColor(mHeaderColor);
mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
canvas.drawRect(0, 0, getWidth(), mHeaderTopPadding + getTranslationY(),
mHeaderPaint);
}
}
public class AdapterHolder {
public static final int MAIN = 0;
public static final int WORK = 1;
@@ -725,4 +770,24 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
return mOverlay;
}
}
protected void updateHeaderScroll(int scrolledOffset) {
float prog = Math.max(0, Math.min(1, (float) scrolledOffset / mHeaderThreshold));
int headerColor = ColorUtils.setAlphaComponent(mHeaderProtectionColor, (int) (prog * 255));
if (headerColor != mHeaderColor) {
mHeaderColor = headerColor;
getSearchView().setBackgroundColor(mHeaderColor);
invalidateHeader();
}
}
/**
* redraws header protection
*/
public void invalidateHeader() {
if (mScrimView != null) {
mScrimView.invalidate();
}
}
}
@@ -38,6 +38,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.logging.StatsLogManager;
@@ -52,6 +53,7 @@ import java.util.List;
public class AllAppsRecyclerView extends BaseRecyclerView {
private static final String TAG = "AllAppsContainerView";
private static final boolean DEBUG = false;
private final Launcher mLauncher;
private AlphabeticalAppsList mApps;
private final int mNumAppsPerRow;
@@ -87,6 +89,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
R.dimen.all_apps_empty_search_bg_top_offset);
mNumAppsPerRow = LauncherAppState.getIDP(context).numColumns;
mFastScrollHelper = new AllAppsFastScrollHelper(this);
mLauncher = Launcher.getLauncher(context);
}
/**
@@ -199,6 +202,12 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
}
}
@Override
public void onScrolled(int dx, int dy) {
super.onScrolled(dx, dy);
mLauncher.getAppsView().updateHeaderScroll(getCurrentScrollY());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
boolean result = super.onInterceptTouchEvent(e);
@@ -410,7 +419,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
/**
* Returns the available scroll height:
* AvailableScrollHeight = Total height of the all items - last page height
* AvailableScrollHeight = Total height of the all items - last page height
*/
@Override
protected int getAvailableScrollHeight() {
@@ -45,6 +45,7 @@ import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.views.ScrimView;
/**
* Handles AllApps view transition.
@@ -88,6 +89,7 @@ public class AllAppsTransitionController
private float mProgress; // [0, 1], mShiftRange * mProgress = shiftCurrent
private float mScrollRangeDelta = 0;
private ScrimView mScrimView;
public AllAppsTransitionController(Launcher l) {
mLauncher = l;
@@ -158,7 +160,7 @@ public class AllAppsTransitionController
Interpolator interpolator = toState.equals(ALL_APPS)
? (config.userControlled ? ACCEL_2 : ACCEL_0_75) :
(config.userControlled ? DEACCEL_2 : DEACCEL);
(config.userControlled ? DEACCEL_2 : DEACCEL);
Animator anim = createSpringAnimation(mProgress, targetProgress);
anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
@@ -181,19 +183,28 @@ public class AllAppsTransitionController
Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
setter.setViewAlpha(mAppsView, hasAllAppsContent ? 1 : 0, allAppsFade);
boolean shouldProtectHeader =
ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS;
mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null);
}
public AnimatorListenerAdapter getProgressAnimatorListener() {
return AnimationSuccessListener.forRunnable(this::onProgressAnimationEnd);
}
public void setupViews(AllAppsContainerView appsView) {
/**
* see Launcher#setupViews
*/
public void setupViews(ScrimView scrimView, AllAppsContainerView appsView) {
mScrimView = scrimView;
mAppsView = appsView;
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && Utilities.ATLEAST_R) {
mLauncher.getSystemUiController().updateUiState(UI_STATE_ALLAPPS,
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
mAppsView.setScrimView(scrimView);
}
/**
+33 -1
View File
@@ -18,6 +18,7 @@ package com.android.launcher3.views;
import static com.android.launcher3.util.SystemUiController.UI_STATE_SCRIM_VIEW;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
@@ -37,13 +38,16 @@ public class ScrimView extends View implements Insettable {
private SystemUiController mSystemUiController;
private ScrimDrawingController mDrawingController;
public ScrimView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(false);
}
@Override
public void setInsets(Rect insets) { }
public void setInsets(Rect insets) {
}
@Override
public boolean hasOverlappingRendering() {
@@ -62,6 +66,14 @@ public class ScrimView extends View implements Insettable {
super.setBackgroundColor(color);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDrawingController != null) {
mDrawingController.drawOnScrim(canvas);
}
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
@@ -96,4 +108,24 @@ public class ScrimView extends View implements Insettable {
return ColorUtils.calculateLuminance(
((ColorDrawable) getBackground()).getColor()) < 0.5f;
}
/**
* Sets drawing controller. Invalidates ScrimView if drawerController has changed.
*/
public void setDrawingController(ScrimDrawingController drawingController) {
if (mDrawingController != drawingController) {
mDrawingController = drawingController;
invalidate();
}
}
/**
* A Utility interface allowing for other surfaces to draw on ScrimView
*/
public interface ScrimDrawingController {
/**
* Called inside ScrimView#OnDraw
*/
void drawOnScrim(Canvas canvas);
}
}