diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2015-05-13 17:40:42 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2015-05-14 14:44:11 -0700 |
commit | 12fb2cc8ec0dd915259beadacf91a131c6a090b9 (patch) | |
tree | 587fa954f4def35e2e6f67bf23947a294c6f7656 | |
parent | fb445cd97d828fa2d9fe3190b25524e39038cd0b (diff) | |
download | android_packages_apps_Trebuchet-12fb2cc8ec0dd915259beadacf91a131c6a090b9.tar.gz android_packages_apps_Trebuchet-12fb2cc8ec0dd915259beadacf91a131c6a090b9.tar.bz2 android_packages_apps_Trebuchet-12fb2cc8ec0dd915259beadacf91a131c6a090b9.zip |
Extending the shadow effect for search bar to lower devices
> Applying the background to the whole container instead of recycleview
Change-Id: Ifc90d05e0e96c41ba9aaf96b906211b101c2e197
-rw-r--r-- | res/layout/apps_list_view.xml | 56 | ||||
-rw-r--r-- | res/values/dimens.xml | 4 | ||||
-rw-r--r-- | src/com/android/launcher3/AppsContainerRecyclerView.java | 4 | ||||
-rw-r--r-- | src/com/android/launcher3/AppsContainerView.java | 123 |
4 files changed, 135 insertions, 52 deletions
diff --git a/res/layout/apps_list_view.xml b/res/layout/apps_list_view.xml index 5e50191ea..03ba646ee 100644 --- a/res/layout/apps_list_view.xml +++ b/res/layout/apps_list_view.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2015 The Android Open Source Project +<!-- + Copyright (C) 2015 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13,44 +14,48 @@ See the License for the specific language governing permissions and limitations under the License. --> -<FrameLayout - xmlns:android="http://schemas.android.com/apk/res/android" +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/apps_list" android:layout_width="match_parent" android:layout_height="match_parent" android:elevation="15dp" - android:visibility="gone" - android:focusableInTouchMode="true"> + android:focusableInTouchMode="true" + android:visibility="gone" > + <com.android.launcher3.AppsContainerRecyclerView android:id="@+id/apps_list_view" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginTop="@dimen/apps_search_bar_height" android:layout_gravity="center_horizontal|top" + android:layout_marginTop="@dimen/apps_search_bar_height" android:clipToPadding="false" - android:focusable="true" - android:descendantFocusability="afterDescendants" /> + android:descendantFocusability="afterDescendants" + android:focusable="true" /> + <LinearLayout android:id="@+id/prediction_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/apps_search_bar_height" android:orientation="horizontal" - android:visibility="invisible"> + android:visibility="invisible" > </LinearLayout> <!-- We always want the search bar on top, so it goes last. --> + <FrameLayout android:id="@+id/header" android:layout_width="match_parent" android:layout_height="@dimen/apps_search_bar_height" - android:background="@drawable/apps_search_bg"> + android:background="@drawable/apps_search_bg" > + <LinearLayout android:id="@+id/app_search_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:visibility="invisible"> + android:visibility="invisible" > + <ImageView android:id="@+id/dismiss_search_button" android:layout_width="wrap_content" @@ -58,29 +63,31 @@ android:layout_gravity="start|center_vertical" android:layout_marginLeft="4dp" android:layout_marginStart="4dp" - android:paddingTop="13dp" - android:paddingBottom="13dp" android:contentDescription="@string/all_apps_button_label" + android:paddingBottom="13dp" + android:paddingTop="13dp" android:src="@drawable/ic_arrow_back_grey" /> + <com.android.launcher3.AppsContainerSearchEditTextView android:id="@+id/app_search_box" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingTop="16dp" - android:paddingBottom="16dp" - android:paddingLeft="8dp" + android:background="@android:color/transparent" + android:focusableInTouchMode="true" + android:gravity="fill_horizontal" android:hint="@string/apps_view_search_bar_hint" + android:imeOptions="actionDone|flagNoExtractUi" android:maxLines="1" - android:singleLine="true" + android:paddingBottom="16dp" + android:paddingLeft="8dp" + android:paddingTop="16dp" android:scrollHorizontally="true" - android:gravity="fill_horizontal" - android:textSize="16sp" + android:singleLine="true" android:textColor="#4c4c4c" android:textColorHint="#9c9c9c" - android:imeOptions="actionDone|flagNoExtractUi" - android:focusableInTouchMode="true" - android:background="@android:color/transparent" /> + android:textSize="16sp" /> </LinearLayout> + <ImageView android:id="@+id/search_button" android:layout_width="wrap_content" @@ -88,9 +95,10 @@ android:layout_gravity="end|center_vertical" android:layout_marginEnd="6dp" android:layout_marginRight="6dp" - android:paddingTop="13dp" - android:paddingBottom="13dp" android:contentDescription="@string/apps_view_search_bar_hint" + android:paddingBottom="13dp" + android:paddingTop="13dp" android:src="@drawable/ic_search_grey" /> </FrameLayout> + </FrameLayout>
\ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 2fa16e7a2..b5acfbdc6 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -71,6 +71,10 @@ <dimen name="drop_target_drag_padding">14dp</dimen> <dimen name="drop_target_text_size">14sp</dimen> + <dimen name="all_apps_header_max_elevation">4dp</dimen> + <dimen name="all_apps_header_scroll_to_elevation">16dp</dimen> + <dimen name="all_apps_header_shadow_height">6dp</dimen> + <!-- Dragging --> <!-- the area at the edge of the screen that makes the workspace go left or right while you're dragging. --> diff --git a/src/com/android/launcher3/AppsContainerRecyclerView.java b/src/com/android/launcher3/AppsContainerRecyclerView.java index 861767e80..95da48fcd 100644 --- a/src/com/android/launcher3/AppsContainerRecyclerView.java +++ b/src/com/android/launcher3/AppsContainerRecyclerView.java @@ -146,9 +146,7 @@ public class AppsContainerRecyclerView extends BaseContainerRecyclerView { mNumPredictedAppsPerRow = numPredictedAppsPerRow; } - @Override - public void setBackground(Drawable background) { - super.setBackground(background); + public void updateBackgroundPadding(Drawable background) { background.getPadding(mBackgroundPadding); } diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java index b752905a2..7c1aee228 100644 --- a/src/com/android/launcher3/AppsContainerView.java +++ b/src/com/android/launcher3/AppsContainerView.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.InsetDrawable; import android.os.Build; import android.support.v7.widget.RecyclerView; @@ -58,9 +59,7 @@ public class AppsContainerView extends BaseContainerView implements DragSource, private static final boolean ALLOW_SINGLE_APP_LAUNCH = true; private static final boolean DYNAMIC_HEADER_ELEVATION = true; private static final boolean DISMISS_SEARCH_ON_BACK = true; - private static final float HEADER_ELEVATION_DP = 4; - // How far the user has to scroll in order to reach the full elevation - private static final float HEADER_SCROLL_TO_ELEVATION_DP = 16; + private static final int FADE_IN_DURATION = 175; private static final int FADE_OUT_DURATION = 100; private static final int SEARCH_TRANSLATION_X_DP = 18; @@ -83,6 +82,8 @@ public class AppsContainerView extends BaseContainerView implements DragSource, private View mDismissSearchButtonView; private AppsContainerSearchEditTextView mSearchBarEditView; + private HeaderElevationController mElevationController; + private int mNumAppsPerRow; private int mNumPredictedAppsPerRow; // This coordinate is relative to this container view @@ -174,6 +175,7 @@ public class AppsContainerView extends BaseContainerView implements DragSource, */ public void hideHeaderBar() { mHeaderView.setVisibility(View.GONE); + mElevationController.disable(); onUpdateBackgrounds(); onUpdatePaddings(); } @@ -219,9 +221,13 @@ public class AppsContainerView extends BaseContainerView implements DragSource, // Fix the header view elevation if not dynamically calculating it mHeaderView = findViewById(R.id.header); mHeaderView.setOnClickListener(this); - if (Utilities.isLmpOrAbove() && !DYNAMIC_HEADER_ELEVATION) { - mHeaderView.setElevation(DynamicGrid.pxFromDp(HEADER_ELEVATION_DP, - getContext().getResources().getDisplayMetrics())); + + mElevationController = Utilities.isLmpOrAbove() ? + new HeaderElevationControllerVL(mHeaderView) : + new HeaderElevationControllerV16(mHeaderView); + if (!DYNAMIC_HEADER_ELEVATION) { + mElevationController.onScroll(getResources() + .getDimensionPixelSize(R.dimen.all_apps_header_scroll_to_elevation)); } // Fix the prediction bar size @@ -335,6 +341,10 @@ public class AppsContainerView extends BaseContainerView implements DragSource, boolean hasSearchBar = (mSearchBarEditView != null) && (mSearchBarEditView.getVisibility() == View.VISIBLE); + // Set the background on the container, but let the recyclerView extend the full screen, + // so that the fast-scroller works on the edge as well. + mContentView.setPadding(0, 0, 0, 0); + if (mFixedBounds.isEmpty()) { // If there are no fixed bounds, then use the default padding and insets setPadding(mInsets.left, mContainerInset + mInsets.top, mInsets.right, @@ -377,19 +387,16 @@ public class AppsContainerView extends BaseContainerView implements DragSource, @Override protected void onUpdateBackgrounds() { int inset = mFixedBounds.isEmpty() ? mContainerInset : mFixedBoundsContainerInset; - boolean hasSearchBar = (mSearchBarEditView != null) && - (mSearchBarEditView.getVisibility() == View.VISIBLE); // Update the background of the reveal view and list to be inset with the fixed bound // insets instead of the default insets // TODO: Use quantum_panel instead of quantum_panel_shape. - mAppsRecyclerView.setBackground(new InsetDrawable( - getContext().getResources().getDrawable( - hasSearchBar ? R.drawable.apps_list_search_bg : R.drawable.quantum_panel_shape), - inset, 0, inset, 0)); - getRevealView().setBackground(new InsetDrawable( + InsetDrawable background = new InsetDrawable( getContext().getResources().getDrawable(R.drawable.quantum_panel_shape), - inset, 0, inset, 0)); + inset, 0, inset, 0); + mContentView.setBackground(background); + mAppsRecyclerView.updateBackgroundPadding(background); + getRevealView().setBackground(background.getConstantState().newDrawable()); } @Override @@ -619,17 +626,8 @@ public class AppsContainerView extends BaseContainerView implements DragSource, */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void onRecyclerViewScrolled() { - if (DYNAMIC_HEADER_ELEVATION && Utilities.isLmpOrAbove()) { - int elevation = DynamicGrid.pxFromDp(HEADER_ELEVATION_DP, - getContext().getResources().getDisplayMetrics()); - int scrollToElevation = DynamicGrid.pxFromDp(HEADER_SCROLL_TO_ELEVATION_DP, - getContext().getResources().getDisplayMetrics()); - float elevationPct = (float) Math.min(mRecyclerViewScrollY, scrollToElevation) / - scrollToElevation; - float newElevation = elevation * elevationPct; - if (Float.compare(mHeaderView.getElevation(), newElevation) != 0) { - mHeaderView.setElevation(newElevation); - } + if (DYNAMIC_HEADER_ELEVATION) { + mElevationController.onScroll(mRecyclerViewScrollY); } mPredictionBarView.setTranslationY(-mRecyclerViewScrollY + mAppsRecyclerView.getPaddingTop()); @@ -839,4 +837,79 @@ public class AppsContainerView extends BaseContainerView implements DragSource, private InputMethodManager getInputMethodManager() { return (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); } + + private static interface HeaderElevationController { + + public void onScroll(int scrollY); + + public void disable(); + } + + private static final class HeaderElevationControllerV16 implements HeaderElevationController { + + private final View mShadow; + + private final float mScrollToElevation; + + public HeaderElevationControllerV16(View header) { + Resources res = header.getContext().getResources(); + mScrollToElevation = res.getDimension(R.dimen.all_apps_header_scroll_to_elevation); + + mShadow = new View(header.getContext()); + mShadow.setBackground(new GradientDrawable( + GradientDrawable.Orientation.TOP_BOTTOM, new int[] {0x44000000, 0x00000000})); + mShadow.setAlpha(0); + + FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( + LayoutParams.MATCH_PARENT, + res.getDimensionPixelSize(R.dimen.all_apps_header_shadow_height)); + lp.topMargin = ((FrameLayout.LayoutParams) header.getLayoutParams()).height; + + ((ViewGroup) header.getParent()).addView(mShadow, lp); + } + + @Override + public void onScroll(int scrollY) { + float elevationPct = (float) Math.min(scrollY, mScrollToElevation) / + mScrollToElevation; + mShadow.setAlpha(elevationPct); + } + + @Override + public void disable() { + ViewGroup parent = (ViewGroup) mShadow.getParent(); + if (parent != null) { + parent.removeView(mShadow); + } + } + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private static final class HeaderElevationControllerVL implements HeaderElevationController { + + private final View mHeader; + private final float mMaxElevation; + private final float mScrollToElevation; + + public HeaderElevationControllerVL(View header) { + mHeader = header; + + Resources res = header.getContext().getResources(); + mMaxElevation = res.getDimension(R.dimen.all_apps_header_max_elevation); + mScrollToElevation = res.getDimension(R.dimen.all_apps_header_scroll_to_elevation); + } + + @Override + public void onScroll(int scrollY) { + float elevationPct = (float) Math.min(scrollY, mScrollToElevation) / + mScrollToElevation; + float newElevation = mMaxElevation * elevationPct; + if (Float.compare(mHeader.getElevation(), newElevation) != 0) { + mHeader.setElevation(newElevation); + } + } + + @Override + public void disable() { } + } } |