diff --git a/res/values/config.xml b/res/values/config.xml
index 04c359ede3..72959b2d5c 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -34,6 +34,9 @@
popup_container_iterate_children
+
+ false
+
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index a4e1af6fb3..21bc479c22 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -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();
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 9c61c1b69f..57a3e1c7bb 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -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();
}
}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 8ea83d56ac..debb5b20c1 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -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, 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 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);
}
}