Merge "[Search] Update AllApps header protection" into sc-v2-dev

This commit is contained in:
Samuel Fufa 2021-08-31 18:08:34 +00:00 committed by Android (Google) Code Review
commit e34c2f8272
4 changed files with 78 additions and 59 deletions

View File

@ -34,6 +34,9 @@
<!-- View tag key used to determine if we should fade in the child views.. -->
<string name="popup_container_iterate_children" translatable="false">popup_container_iterate_children</string>
<!-- config used to determine if header protection is supported in AllApps -->
<bool name="config_header_protection_supported">false</bool>
<!-- Workspace -->
<!-- The duration (in ms) of the fade animation on the object outlines, used when
we are dragging objects around on the home screen. -->

View File

@ -99,8 +99,18 @@ public class ExtendedEditText extends EditText {
}
}
// inherited class can override to change the appearance of the edit text.
public void show() {}
/**
* Sets whether EditText background should be visible
* @param maxAlpha defines the maximum alpha the background should animates to
*/
public void setBackgroundVisibility(boolean visible, float maxAlpha) {}
/**
* Returns whether a visible background is set on EditText
*/
public boolean getBackgroundVisibility() {
return getBackground() != null;
}
public void showKeyboard() {
mShowImeAfterFirstLayout = !showSoftInput();

View File

@ -59,6 +59,7 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Insettable;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.R;
@ -118,7 +119,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
private SpannableStringBuilder mSearchQueryBuilder = null;
protected boolean mUsingTabs;
private boolean mSearchModeWhileUsingTabs = false;
private boolean mIsSearching;
protected RecyclerViewFastScroller mTouchHandler;
protected final Point mFastScrollerOffset = new Point();
@ -132,6 +133,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
private final float mHeaderThreshold;
private ScrimView mScrimView;
private int mHeaderColor;
private int mTabsProtectionAlpha;
public AllAppsContainerView(Context context) {
this(context, null);
@ -625,18 +627,19 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
for (int i = 0; i < mAH.length; i++) {
mAH[i].adapter.setLastSearchQuery(query);
}
mIsSearching = true;
if (mUsingTabs) {
mSearchModeWhileUsingTabs = true;
rebindAdapters(false); // hide tabs
}
mHeader.setCollapsed(true);
}
public void onClearSearchResult() {
if (mSearchModeWhileUsingTabs) {
if (mUsingTabs) {
rebindAdapters(true); // show tabs
mSearchModeWhileUsingTabs = false;
}
mIsSearching = false;
getActiveRecyclerView().scrollToTop();
}
public void onSearchResultsChanged() {
@ -710,13 +713,12 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
mHeaderPaint.setColor(mHeaderColor);
mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
int bottom = mUsingTabs && mHeader.mHeaderCollapsed ? mHeader.getVisibleBottomBound()
: mSearchContainer.getBottom();
canvas.drawRect(0, 0, canvas.getWidth(), bottom + getTranslationY(),
mHeaderPaint);
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && getTranslationY() == 0) {
mSearchUiManager.getEditText().setBackground(null);
int bottom = (int) (mSearchContainer.getBottom() + getTranslationY());
canvas.drawRect(0, 0, canvas.getWidth(), bottom, mHeaderPaint);
int tabsHeight = getFloatingHeaderView().getPeripheralProtectionHeight();
if (mTabsProtectionAlpha > 0 && tabsHeight != 0) {
mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha));
canvas.drawRect(0, bottom, canvas.getWidth(), bottom + tabsHeight, mHeaderPaint);
}
}
}
@ -796,18 +798,29 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
protected void updateHeaderScroll(int scrolledOffset) {
float prog = Math.max(0, Math.min(1, (float) scrolledOffset / mHeaderThreshold));
float prog = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f);
int viewBG = ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, prog);
int headerColor = ColorUtils.setAlphaComponent(viewBG,
(int) (getSearchView().getAlpha() * 255));
if (headerColor != mHeaderColor) {
int tabsAlpha = mHeader.getPeripheralProtectionHeight() == 0 ? 0
: (int) (Utilities.boundToRange(
(scrolledOffset + mHeader.mSnappedScrolledY) / mHeaderThreshold, 0f, 1f)
* 255);
if (headerColor != mHeaderColor || mTabsProtectionAlpha != tabsAlpha) {
mHeaderColor = headerColor;
getSearchView().setBackgroundColor(viewBG);
getFloatingHeaderView().setHeaderColor(viewBG);
mTabsProtectionAlpha = tabsAlpha;
invalidateHeader();
if (scrolledOffset == 0 && mSearchUiManager.getEditText() != null) {
mSearchUiManager.getEditText().show();
}
if (mSearchUiManager.getEditText() != null) {
ExtendedEditText editText = mSearchUiManager.getEditText();
boolean bgVisible = editText.getBackgroundVisibility();
if (scrolledOffset == 0 && !mIsSearching) {
bgVisible = true;
} else if (scrolledOffset > mHeaderThreshold) {
bgVisible = false;
}
editText.setBackgroundVisibility(bgVisible, 1 - prog);
}
}
@ -815,7 +828,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
* redraws header protection
*/
public void invalidateHeader() {
if (mScrimView != null && FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
if (mScrimView != null && mHeader.isHeaderProtectionSupported()) {
mScrimView.invalidate();
}
}

View File

@ -17,9 +17,6 @@ package com.android.launcher3.allapps;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.ArrayMap;
@ -50,11 +47,10 @@ public class FloatingHeaderView extends LinearLayout implements
ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow>, Insettable,
OnHeightUpdatedListener {
private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
private final Rect mRVClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
private final Rect mHeaderClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
private final ValueAnimator mHeaderAnimator = ValueAnimator.ofInt(0, 1).setDuration(100);
private final Point mTempOffset = new Point();
private final Paint mBGPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final RecyclerView.OnScrollListener mOnScrollListener =
new RecyclerView.OnScrollListener() {
@Override
@ -82,19 +78,19 @@ public class FloatingHeaderView extends LinearLayout implements
}
};
private final int mHeaderTopPadding;
protected final Map<AllAppsRow, PluginHeaderRow> mPluginRows = new ArrayMap<>();
private final int mHeaderTopPadding;
private final boolean mHeaderProtectionSupported;
protected ViewGroup mTabLayout;
private AllAppsRecyclerView mMainRV;
private AllAppsRecyclerView mWorkRV;
private AllAppsRecyclerView mCurrentRV;
private ViewGroup mParent;
public boolean mHeaderCollapsed;
private int mSnappedScrolledY;
protected int mSnappedScrolledY;
private int mTranslationY;
private int mHeaderColor;
private boolean mForwardToRecyclerView;
@ -120,6 +116,8 @@ public class FloatingHeaderView extends LinearLayout implements
super(context, attrs);
mHeaderTopPadding = context.getResources()
.getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
mHeaderProtectionSupported = context.getResources().getBoolean(
R.bool.config_header_protection_supported);
}
@Override
@ -138,7 +136,6 @@ public class FloatingHeaderView extends LinearLayout implements
}
mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]);
mAllRows = mFixedRows;
mHeaderAnimator.addUpdateListener(valueAnimator -> invalidate());
}
@Override
@ -285,7 +282,7 @@ public class FloatingHeaderView extends LinearLayout implements
mHeaderCollapsed = false;
}
mTranslationY = currentScrollY;
} else if (!mHeaderCollapsed) {
} else {
mTranslationY = currentScrollY - mSnappedScrolledY - mMaxTranslation;
// update state vars
@ -295,31 +292,10 @@ public class FloatingHeaderView extends LinearLayout implements
} else if (mTranslationY <= -mMaxTranslation) { // hide or stay hidden
mHeaderCollapsed = true;
mSnappedScrolledY = -mMaxTranslation;
mHeaderAnimator.setCurrentFraction(0);
mHeaderAnimator.start();
}
}
}
/**
* Set current header protection background color
*/
public void setHeaderColor(int color) {
mHeaderColor = color;
invalidate();
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (mHeaderCollapsed && !mCollapsed && mTabLayout.getVisibility() == VISIBLE
&& mHeaderColor != Color.TRANSPARENT && FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
mBGPaint.setColor(mHeaderColor);
mBGPaint.setAlpha((int) (255 * mHeaderAnimator.getAnimatedFraction()));
canvas.drawRect(0, 0, getWidth(), getHeight() + mTranslationY, mBGPaint);
}
super.dispatchDraw(canvas);
}
protected void applyVerticalMove() {
int uncappedTranslationY = mTranslationY;
mTranslationY = Math.max(mTranslationY, -mMaxTranslation);
@ -336,11 +312,15 @@ public class FloatingHeaderView extends LinearLayout implements
}
mTabLayout.setTranslationY(mTranslationY);
mClip.top = mMaxTranslation + mTranslationY;
int clipHeight = mHeaderTopPadding - getPaddingBottom();
mRVClip.top = mTabsHidden ? clipHeight : 0;
mHeaderClip.top = clipHeight;
// clipping on a draw might cause additional redraw
mMainRV.setClipBounds(mClip);
setClipBounds(mHeaderClip);
mMainRV.setClipBounds(mRVClip);
if (mWorkRV != null) {
mWorkRV.setClipBounds(mClip);
mWorkRV.setClipBounds(mRVClip);
}
}
@ -421,6 +401,10 @@ public class FloatingHeaderView extends LinearLayout implements
return false;
}
public boolean isHeaderProtectionSupported() {
return mHeaderProtectionSupported;
}
@Override
public boolean hasOverlappingRendering() {
return false;
@ -444,10 +428,19 @@ public class FloatingHeaderView extends LinearLayout implements
}
/**
* Returns visible height of FloatingHeaderView contents
* Returns visible height of FloatingHeaderView contents requiring header protection
*/
public int getVisibleBottomBound() {
return getBottom() + mTranslationY;
public int getPeripheralProtectionHeight() {
if (!mHeaderProtectionSupported) {
return 0;
}
// we only want to show protection when work tab is available and header is either
// collapsed or animating to/from collapsed state
if (mTabsHidden || !mHeaderCollapsed) {
return 0;
}
return Math.max(getHeight() - getPaddingTop() + mTranslationY, 0);
}
}