Loading res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -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. --> Loading src/com/android/launcher3/ExtendedEditText.java +12 −2 Original line number Diff line number Diff line Loading @@ -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(); Loading src/com/android/launcher3/allapps/AllAppsContainerView.java +31 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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() { Loading Loading @@ -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); } } } Loading Loading @@ -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); } } Loading @@ -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(); } } Loading src/com/android/launcher3/allapps/FloatingHeaderView.java +32 −39 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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; Loading @@ -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 Loading @@ -138,7 +136,6 @@ public class FloatingHeaderView extends LinearLayout implements } mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]); mAllRows = mFixedRows; mHeaderAnimator.addUpdateListener(valueAnimator -> invalidate()); } @Override Loading Loading @@ -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 Loading @@ -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); Loading @@ -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); } } Loading Loading @@ -421,6 +401,10 @@ public class FloatingHeaderView extends LinearLayout implements return false; } public boolean isHeaderProtectionSupported() { return mHeaderProtectionSupported; } @Override public boolean hasOverlappingRendering() { return false; Loading @@ -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); } } Loading Loading
res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -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. --> Loading
src/com/android/launcher3/ExtendedEditText.java +12 −2 Original line number Diff line number Diff line Loading @@ -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(); Loading
src/com/android/launcher3/allapps/AllAppsContainerView.java +31 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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() { Loading Loading @@ -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); } } } Loading Loading @@ -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); } } Loading @@ -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(); } } Loading
src/com/android/launcher3/allapps/FloatingHeaderView.java +32 −39 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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; Loading @@ -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 Loading @@ -138,7 +136,6 @@ public class FloatingHeaderView extends LinearLayout implements } mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]); mAllRows = mFixedRows; mHeaderAnimator.addUpdateListener(valueAnimator -> invalidate()); } @Override Loading Loading @@ -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 Loading @@ -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); Loading @@ -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); } } Loading Loading @@ -421,6 +401,10 @@ public class FloatingHeaderView extends LinearLayout implements return false; } public boolean isHeaderProtectionSupported() { return mHeaderProtectionSupported; } @Override public boolean hasOverlappingRendering() { return false; Loading @@ -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); } } Loading