Merge "[Search] Update AllApps header protection" into sc-v2-dev
This commit is contained in:
commit
e34c2f8272
|
@ -34,6 +34,9 @@
|
||||||
<!-- View tag key used to determine if we should fade in the child views.. -->
|
<!-- 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>
|
<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 -->
|
<!-- Workspace -->
|
||||||
<!-- The duration (in ms) of the fade animation on the object outlines, used when
|
<!-- The duration (in ms) of the fade animation on the object outlines, used when
|
||||||
we are dragging objects around on the home screen. -->
|
we are dragging objects around on the home screen. -->
|
||||||
|
|
|
@ -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() {
|
public void showKeyboard() {
|
||||||
mShowImeAfterFirstLayout = !showSoftInput();
|
mShowImeAfterFirstLayout = !showSoftInput();
|
||||||
|
|
|
@ -59,6 +59,7 @@ import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
||||||
import com.android.launcher3.DragSource;
|
import com.android.launcher3.DragSource;
|
||||||
import com.android.launcher3.DropTarget.DragObject;
|
import com.android.launcher3.DropTarget.DragObject;
|
||||||
|
import com.android.launcher3.ExtendedEditText;
|
||||||
import com.android.launcher3.Insettable;
|
import com.android.launcher3.Insettable;
|
||||||
import com.android.launcher3.InsettableFrameLayout;
|
import com.android.launcher3.InsettableFrameLayout;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
|
@ -118,7 +119,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
|
||||||
private SpannableStringBuilder mSearchQueryBuilder = null;
|
private SpannableStringBuilder mSearchQueryBuilder = null;
|
||||||
|
|
||||||
protected boolean mUsingTabs;
|
protected boolean mUsingTabs;
|
||||||
private boolean mSearchModeWhileUsingTabs = false;
|
private boolean mIsSearching;
|
||||||
|
|
||||||
protected RecyclerViewFastScroller mTouchHandler;
|
protected RecyclerViewFastScroller mTouchHandler;
|
||||||
protected final Point mFastScrollerOffset = new Point();
|
protected final Point mFastScrollerOffset = new Point();
|
||||||
|
@ -132,6 +133,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
|
||||||
private final float mHeaderThreshold;
|
private final float mHeaderThreshold;
|
||||||
private ScrimView mScrimView;
|
private ScrimView mScrimView;
|
||||||
private int mHeaderColor;
|
private int mHeaderColor;
|
||||||
|
private int mTabsProtectionAlpha;
|
||||||
|
|
||||||
public AllAppsContainerView(Context context) {
|
public AllAppsContainerView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
|
@ -625,18 +627,19 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
|
||||||
for (int i = 0; i < mAH.length; i++) {
|
for (int i = 0; i < mAH.length; i++) {
|
||||||
mAH[i].adapter.setLastSearchQuery(query);
|
mAH[i].adapter.setLastSearchQuery(query);
|
||||||
}
|
}
|
||||||
|
mIsSearching = true;
|
||||||
if (mUsingTabs) {
|
if (mUsingTabs) {
|
||||||
mSearchModeWhileUsingTabs = true;
|
|
||||||
rebindAdapters(false); // hide tabs
|
rebindAdapters(false); // hide tabs
|
||||||
}
|
}
|
||||||
mHeader.setCollapsed(true);
|
mHeader.setCollapsed(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onClearSearchResult() {
|
public void onClearSearchResult() {
|
||||||
if (mSearchModeWhileUsingTabs) {
|
if (mUsingTabs) {
|
||||||
rebindAdapters(true); // show tabs
|
rebindAdapters(true); // show tabs
|
||||||
mSearchModeWhileUsingTabs = false;
|
|
||||||
}
|
}
|
||||||
|
mIsSearching = false;
|
||||||
|
getActiveRecyclerView().scrollToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSearchResultsChanged() {
|
public void onSearchResultsChanged() {
|
||||||
|
@ -710,13 +713,12 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
|
||||||
mHeaderPaint.setColor(mHeaderColor);
|
mHeaderPaint.setColor(mHeaderColor);
|
||||||
mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
|
mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
|
||||||
if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
|
if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
|
||||||
int bottom = mUsingTabs && mHeader.mHeaderCollapsed ? mHeader.getVisibleBottomBound()
|
int bottom = (int) (mSearchContainer.getBottom() + getTranslationY());
|
||||||
: mSearchContainer.getBottom();
|
canvas.drawRect(0, 0, canvas.getWidth(), bottom, mHeaderPaint);
|
||||||
canvas.drawRect(0, 0, canvas.getWidth(), bottom + getTranslationY(),
|
int tabsHeight = getFloatingHeaderView().getPeripheralProtectionHeight();
|
||||||
mHeaderPaint);
|
if (mTabsProtectionAlpha > 0 && tabsHeight != 0) {
|
||||||
|
mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha));
|
||||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && getTranslationY() == 0) {
|
canvas.drawRect(0, bottom, canvas.getWidth(), bottom + tabsHeight, mHeaderPaint);
|
||||||
mSearchUiManager.getEditText().setBackground(null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -796,18 +798,29 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
|
||||||
|
|
||||||
|
|
||||||
protected void updateHeaderScroll(int scrolledOffset) {
|
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 viewBG = ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, prog);
|
||||||
int headerColor = ColorUtils.setAlphaComponent(viewBG,
|
int headerColor = ColorUtils.setAlphaComponent(viewBG,
|
||||||
(int) (getSearchView().getAlpha() * 255));
|
(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;
|
mHeaderColor = headerColor;
|
||||||
getSearchView().setBackgroundColor(viewBG);
|
mTabsProtectionAlpha = tabsAlpha;
|
||||||
getFloatingHeaderView().setHeaderColor(viewBG);
|
|
||||||
invalidateHeader();
|
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
|
* redraws header protection
|
||||||
*/
|
*/
|
||||||
public void invalidateHeader() {
|
public void invalidateHeader() {
|
||||||
if (mScrimView != null && FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
if (mScrimView != null && mHeader.isHeaderProtectionSupported()) {
|
||||||
mScrimView.invalidate();
|
mScrimView.invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,6 @@ package com.android.launcher3.allapps;
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
|
@ -50,11 +47,10 @@ public class FloatingHeaderView extends LinearLayout implements
|
||||||
ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow>, Insettable,
|
ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow>, Insettable,
|
||||||
OnHeightUpdatedListener {
|
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 mAnimator = ValueAnimator.ofInt(0, 0);
|
||||||
private final ValueAnimator mHeaderAnimator = ValueAnimator.ofInt(0, 1).setDuration(100);
|
|
||||||
private final Point mTempOffset = new Point();
|
private final Point mTempOffset = new Point();
|
||||||
private final Paint mBGPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
||||||
private final RecyclerView.OnScrollListener mOnScrollListener =
|
private final RecyclerView.OnScrollListener mOnScrollListener =
|
||||||
new RecyclerView.OnScrollListener() {
|
new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -82,19 +78,19 @@ public class FloatingHeaderView extends LinearLayout implements
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final int mHeaderTopPadding;
|
|
||||||
|
|
||||||
protected final Map<AllAppsRow, PluginHeaderRow> mPluginRows = new ArrayMap<>();
|
protected final Map<AllAppsRow, PluginHeaderRow> mPluginRows = new ArrayMap<>();
|
||||||
|
|
||||||
|
private final int mHeaderTopPadding;
|
||||||
|
private final boolean mHeaderProtectionSupported;
|
||||||
|
|
||||||
protected ViewGroup mTabLayout;
|
protected ViewGroup mTabLayout;
|
||||||
private AllAppsRecyclerView mMainRV;
|
private AllAppsRecyclerView mMainRV;
|
||||||
private AllAppsRecyclerView mWorkRV;
|
private AllAppsRecyclerView mWorkRV;
|
||||||
private AllAppsRecyclerView mCurrentRV;
|
private AllAppsRecyclerView mCurrentRV;
|
||||||
private ViewGroup mParent;
|
private ViewGroup mParent;
|
||||||
public boolean mHeaderCollapsed;
|
public boolean mHeaderCollapsed;
|
||||||
private int mSnappedScrolledY;
|
protected int mSnappedScrolledY;
|
||||||
private int mTranslationY;
|
private int mTranslationY;
|
||||||
private int mHeaderColor;
|
|
||||||
|
|
||||||
private boolean mForwardToRecyclerView;
|
private boolean mForwardToRecyclerView;
|
||||||
|
|
||||||
|
@ -120,6 +116,8 @@ public class FloatingHeaderView extends LinearLayout implements
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
mHeaderTopPadding = context.getResources()
|
mHeaderTopPadding = context.getResources()
|
||||||
.getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
|
.getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
|
||||||
|
mHeaderProtectionSupported = context.getResources().getBoolean(
|
||||||
|
R.bool.config_header_protection_supported);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -138,7 +136,6 @@ public class FloatingHeaderView extends LinearLayout implements
|
||||||
}
|
}
|
||||||
mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]);
|
mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]);
|
||||||
mAllRows = mFixedRows;
|
mAllRows = mFixedRows;
|
||||||
mHeaderAnimator.addUpdateListener(valueAnimator -> invalidate());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -285,7 +282,7 @@ public class FloatingHeaderView extends LinearLayout implements
|
||||||
mHeaderCollapsed = false;
|
mHeaderCollapsed = false;
|
||||||
}
|
}
|
||||||
mTranslationY = currentScrollY;
|
mTranslationY = currentScrollY;
|
||||||
} else if (!mHeaderCollapsed) {
|
} else {
|
||||||
mTranslationY = currentScrollY - mSnappedScrolledY - mMaxTranslation;
|
mTranslationY = currentScrollY - mSnappedScrolledY - mMaxTranslation;
|
||||||
|
|
||||||
// update state vars
|
// update state vars
|
||||||
|
@ -295,31 +292,10 @@ public class FloatingHeaderView extends LinearLayout implements
|
||||||
} else if (mTranslationY <= -mMaxTranslation) { // hide or stay hidden
|
} else if (mTranslationY <= -mMaxTranslation) { // hide or stay hidden
|
||||||
mHeaderCollapsed = true;
|
mHeaderCollapsed = true;
|
||||||
mSnappedScrolledY = -mMaxTranslation;
|
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() {
|
protected void applyVerticalMove() {
|
||||||
int uncappedTranslationY = mTranslationY;
|
int uncappedTranslationY = mTranslationY;
|
||||||
mTranslationY = Math.max(mTranslationY, -mMaxTranslation);
|
mTranslationY = Math.max(mTranslationY, -mMaxTranslation);
|
||||||
|
@ -336,11 +312,15 @@ public class FloatingHeaderView extends LinearLayout implements
|
||||||
}
|
}
|
||||||
|
|
||||||
mTabLayout.setTranslationY(mTranslationY);
|
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
|
// clipping on a draw might cause additional redraw
|
||||||
mMainRV.setClipBounds(mClip);
|
setClipBounds(mHeaderClip);
|
||||||
|
mMainRV.setClipBounds(mRVClip);
|
||||||
if (mWorkRV != null) {
|
if (mWorkRV != null) {
|
||||||
mWorkRV.setClipBounds(mClip);
|
mWorkRV.setClipBounds(mRVClip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,6 +401,10 @@ public class FloatingHeaderView extends LinearLayout implements
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isHeaderProtectionSupported() {
|
||||||
|
return mHeaderProtectionSupported;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasOverlappingRendering() {
|
public boolean hasOverlappingRendering() {
|
||||||
return false;
|
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() {
|
public int getPeripheralProtectionHeight() {
|
||||||
return getBottom() + mTranslationY;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue