10ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalpackage com.android.launcher3.allapps; 20ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 30ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.annotation.TargetApi; 40ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.content.res.Resources; 5cbea0862846a9f5d999111e66c162e2349b6be26Peter Schillerimport android.graphics.Outline; 60ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.graphics.Rect; 70ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.graphics.drawable.GradientDrawable; 80ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.os.Build; 90ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.support.v7.widget.RecyclerView; 100ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.view.View; 110ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.view.ViewGroup; 120ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.view.ViewOutlineProvider; 130ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport android.widget.FrameLayout; 140ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 152e22b5d2de066245f8c8f52343bb2a8b4e8eb563Peter Schillerimport com.android.launcher3.BaseRecyclerView; 160ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalimport com.android.launcher3.R; 170ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 180ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal/** 190ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal * Helper class for controlling the header elevation in response to RecyclerView scroll. 200ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal */ 210ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyalpublic abstract class HeaderElevationController extends RecyclerView.OnScrollListener { 220ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 230ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private int mCurrentY = 0; 240ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 250ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public void reset() { 260ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mCurrentY = 0; 270ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal onScroll(mCurrentY); 280ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 290ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 300ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal @Override 310ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public final void onScrolled(RecyclerView recyclerView, int dx, int dy) { 322e22b5d2de066245f8c8f52343bb2a8b4e8eb563Peter Schiller mCurrentY = ((BaseRecyclerView) recyclerView).getCurrentScrollY(); 330ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal onScroll(mCurrentY); 340ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 350ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 360ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public void updateBackgroundPadding(Rect bgPadding) { } 370ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 380ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal abstract void onScroll(int scrollY); 390ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 400ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public static class ControllerV16 extends HeaderElevationController { 410ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 420ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private final View mShadow; 430ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private final float mScrollToElevation; 440ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 450ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public ControllerV16(View header) { 460ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal Resources res = header.getContext().getResources(); 470ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mScrollToElevation = res.getDimension(R.dimen.all_apps_header_scroll_to_elevation); 480ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 490ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mShadow = new View(header.getContext()); 500ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mShadow.setBackground(new GradientDrawable( 510ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal GradientDrawable.Orientation.TOP_BOTTOM, new int[] {0x1E000000, 0x00000000})); 520ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mShadow.setAlpha(0); 530ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 540ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( 550ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal FrameLayout.LayoutParams.MATCH_PARENT, 560ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal res.getDimensionPixelSize(R.dimen.all_apps_header_shadow_height)); 570ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal lp.topMargin = ((FrameLayout.LayoutParams) header.getLayoutParams()).height; 580ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 590ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal ((ViewGroup) header.getParent()).addView(mShadow, lp); 600ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 610ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 620ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal @Override 630ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public void onScroll(int scrollY) { 640ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal float elevationPct = (float) Math.min(scrollY, mScrollToElevation) / 650ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mScrollToElevation; 660ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mShadow.setAlpha(elevationPct); 670ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 680ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 690ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal @Override 700ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public void updateBackgroundPadding(Rect bgPadding) { 710ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mShadow.getLayoutParams(); 720ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal lp.leftMargin = bgPadding.left; 730ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal lp.rightMargin = bgPadding.right; 740ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mShadow.requestLayout(); 750ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 760ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 770ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 780ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal @TargetApi(Build.VERSION_CODES.LOLLIPOP) 790ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public static class ControllerVL extends HeaderElevationController { 800ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 810ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private final View mHeader; 820ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private final float mMaxElevation; 830ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal private final float mScrollToElevation; 840ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 850ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public ControllerVL(View header) { 860ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mHeader = header; 87cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller Resources res = mHeader.getContext().getResources(); 880ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mMaxElevation = res.getDimension(R.dimen.all_apps_header_max_elevation); 890ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mScrollToElevation = res.getDimension(R.dimen.all_apps_header_scroll_to_elevation); 90cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller 91cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller // We need to provide a custom outline so the shadow only appears on the bottom edge. 92cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller // The top, left and right edges are all extended out, and the shadow is clipped 93cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller // by the parent. 94cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller final ViewOutlineProvider vop = new ViewOutlineProvider() { 95cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller @Override 96cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller public void getOutline(View view, Outline outline) { 97cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller final View parent = (View) mHeader.getParent(); 98cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller 99cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller final int left = parent.getLeft(); // Use the parent to account for offsets 100cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller final int top = view.getTop(); 101cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller final int right = left + view.getWidth(); 102cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller final int bottom = view.getBottom(); 103cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller 104cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller outline.setRect( 105cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller left - (int) mMaxElevation, 106cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller top - (int) mMaxElevation, 107cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller right + (int) mMaxElevation, 108cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller bottom); 109cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller } 110cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller }; 111cbea0862846a9f5d999111e66c162e2349b6be26Peter Schiller mHeader.setOutlineProvider(vop); 1120ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 1130ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal 1140ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal @Override 1150ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal public void onScroll(int scrollY) { 1160ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal float elevationPct = Math.min(scrollY, mScrollToElevation) / mScrollToElevation; 1170ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal float newElevation = mMaxElevation * elevationPct; 1180ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal if (Float.compare(mHeader.getElevation(), newElevation) != 0) { 1190ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal mHeader.setElevation(newElevation); 1200ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 1210ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 1220ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal } 1230ac7ede56afebe4401c0636196f5844be573ad68Sunny Goyal} 124