Extending the shadow effect for search bar to lower devices
> Applying the background to the whole container instead of recycleview Change-Id: Ifc90d05e0e96c41ba9aaf96b906211b101c2e197
This commit is contained in:
parent
fb445cd97d
commit
12fb2cc8ec
|
@ -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: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:paddingBottom="16dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:hint="@string/apps_view_search_bar_hint"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
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>
|
|
@ -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. -->
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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() { }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue