diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2018-03-01 16:29:15 -0800 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2018-03-06 11:41:43 -0800 |
commit | 3661bfac0b810132c44df6c910f5374e76213004 (patch) | |
tree | 85c13e8730794f1436f743b10809b9da331e8780 /src/com | |
parent | 46d259d9fb7b918ee5fee773ee615dd9111aa89f (diff) | |
download | android_packages_apps_Trebuchet-3661bfac0b810132c44df6c910f5374e76213004.tar.gz android_packages_apps_Trebuchet-3661bfac0b810132c44df6c910f5374e76213004.tar.bz2 android_packages_apps_Trebuchet-3661bfac0b810132c44df6c910f5374e76213004.zip |
Fixing fast scroller touch handling in all-apps and widget sheet
Also removing scrim view, instead drawing the scrim manually
Bug: 73085356
Change-Id: I188c6c9b1685e22d5d97b38dd5d3e960b655c9ba
Diffstat (limited to 'src/com')
7 files changed, 137 insertions, 80 deletions
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java index cc1326338..74b9cfaf3 100644 --- a/src/com/android/launcher3/BaseRecyclerView.java +++ b/src/com/android/launcher3/BaseRecyclerView.java @@ -33,8 +33,7 @@ import com.android.launcher3.views.RecyclerViewFastScroller; * <li> Enable fast scroller. * </ul> */ -public abstract class BaseRecyclerView extends RecyclerView - implements RecyclerView.OnItemTouchListener { +public abstract class BaseRecyclerView extends RecyclerView { protected RecyclerViewFastScroller mScrollbar; @@ -51,12 +50,6 @@ public abstract class BaseRecyclerView extends RecyclerView } @Override - protected void onFinishInflate() { - super.onFinishInflate(); - addOnItemTouchListener(this); - } - - @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); bindFastScrollbar(); @@ -69,40 +62,8 @@ public abstract class BaseRecyclerView extends RecyclerView onUpdateScrollbar(0); } - /** - * We intercept the touch handling only to support fast scrolling when initiated from the - * scroll bar. Otherwise, we fall back to the default RecyclerView touch handling. - */ - @Override - public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent ev) { - return handleTouchEvent(ev); - } - - @Override - public void onTouchEvent(RecyclerView rv, MotionEvent ev) { - handleTouchEvent(ev); - } - - /** - * Handles the touch event and determines whether to show the fast scroller (or updates it if - * it is already showing). - */ - private boolean handleTouchEvent(MotionEvent ev) { - // Move to mScrollbar's coordinate system. - // We need to take parent into account (view pager's location) - ViewGroup parent = (ViewGroup) getParent(); - int left = parent.getLeft() - mScrollbar.getLeft(); - int top = parent.getTop() + getTop() - mScrollbar.getTop() - getScrollBarTop(); - ev.offsetLocation(left, top); - try { - return mScrollbar.handleTouchEvent(ev); - } finally { - ev.offsetLocation(-left, -top); - } - } - - public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { - // DO NOT REMOVE, NEEDED IMPLEMENTATION FOR M BUILDS + public RecyclerViewFastScroller getScrollbar() { + return mScrollbar; } public int getScrollBarTop() { diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 5cd54caec..26922ad8d 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -18,6 +18,9 @@ package com.android.launcher3.allapps; import static com.android.launcher3.anim.Interpolators.DEACCEL_2; import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Point; import android.graphics.Rect; import android.os.Process; import android.support.annotation.NonNull; @@ -57,6 +60,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BottomUserEducationView; +import com.android.launcher3.views.RecyclerViewFastScroller; /** * The all apps view container. @@ -70,6 +74,9 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, private final ItemInfoMatcher mWorkMatcher = ItemInfoMatcher.not(mPersonalMatcher); private final AllAppsStore mAllAppsStore = new AllAppsStore(); + private final Paint mNavBarScrimPaint; + private int mNavBarScrimHeight = 0; + private SearchUiManager mSearchUiManager; private View mSearchContainer; private AllAppsPagedView mViewPager; @@ -80,6 +87,9 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, private boolean mUsingTabs; private boolean mSearchModeWhileUsingTabs = false; + private RecyclerViewFastScroller mTouchHandler; + private final Point mFastScrollerOffset = new Point(); + public AllAppsContainerView(Context context) { this(context, null); } @@ -101,6 +111,9 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, mAH[AdapterHolder.MAIN] = new AdapterHolder(false /* isWork */); mAH[AdapterHolder.WORK] = new AdapterHolder(true /* isWork */); + mNavBarScrimPaint = new Paint(); + mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor)); + mAllAppsStore.addUpdateListener(this::onAppsUpdated); // Attach a scrim to be drawn behind all-apps and hotseat @@ -108,27 +121,11 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, .attach(); } - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - applyTouchDelegate(); - } - - private void applyTouchDelegate() { - // TODO: Reimplement once fast scroller is fixed. - } - public AllAppsStore getAppsStore() { return mAllAppsStore; } @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); - applyTouchDelegate(); - } - - @Override public void onDeviceProfileChanged(DeviceProfile dp) { for (AdapterHolder holder : mAH) { if (holder.recyclerView != null) { @@ -163,7 +160,38 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, return true; } AllAppsRecyclerView rv = getActiveRecyclerView(); - return rv == null || rv.shouldContainerScroll(ev, mLauncher.getDragLayer()); + if (rv == null) { + return true; + } + if (rv.getScrollbar().getThumbOffsetY() >= 0 && + mLauncher.getDragLayer().isEventOverView(rv.getScrollbar(), ev)) { + return false; + } + return rv.shouldContainerScroll(ev, mLauncher.getDragLayer()); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + AllAppsRecyclerView rv = getActiveRecyclerView(); + if (rv != null && + rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) { + mTouchHandler = rv.getScrollbar(); + } + } + if (mTouchHandler != null) { + return mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset); + } + return false; + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + if (mTouchHandler != null) { + mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset); + return true; + } + return false; } public AllAppsRecyclerView getActiveRecyclerView() { @@ -282,14 +310,20 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, } setLayoutParams(mlp); - View navBarBg = findViewById(R.id.nav_bar_bg); - ViewGroup.LayoutParams navBarBgLp = navBarBg.getLayoutParams(); - navBarBgLp.height = insets.bottom; - navBarBg.setLayoutParams(navBarBgLp); - + mNavBarScrimHeight = insets.bottom; InsettableFrameLayout.dispatchInsets(this, insets); } + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + + if (mNavBarScrimHeight > 0) { + canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(), + mNavBarScrimPaint); + } + } + public SpringAnimationHandler getSpringAnimationHandler() { return mUsingTabs ? null : mAH[AdapterHolder.MAIN].animationHandler; } @@ -320,8 +354,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, mAllAppsStore.registerIconContainer(mAH[AdapterHolder.MAIN].recyclerView); mAllAppsStore.registerIconContainer(mAH[AdapterHolder.WORK].recyclerView); - - applyTouchDelegate(); } private void replaceRVContainer(boolean showTabs) { @@ -352,7 +384,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource, public void onTabChanged(int pos) { mHeader.setMainActive(pos == 0); reset(); - applyTouchDelegate(); if (mAH[pos].recyclerView != null) { mAH[pos].recyclerView.bindFastScrollbar(); diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 53d19eb74..4a393c9b9 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -97,7 +97,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine int defStyleRes) { super(context, attrs, defStyleAttr); Resources res = getResources(); - addOnItemTouchListener(this); mEmptySearchBackgroundTopOffset = res.getDimensionPixelSize( R.dimen.all_apps_empty_search_bg_top_offset); diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java index 58c914803..1cd669986 100644 --- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java +++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java @@ -22,6 +22,8 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.Rect; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.util.Property; @@ -43,6 +45,7 @@ import com.android.launcher3.util.Themes; public class RecyclerViewFastScroller extends View { private static final int SCROLL_DELTA_THRESHOLD_DP = 4; + private static final Rect sTempRect = new Rect(); private static final Property<RecyclerViewFastScroller, Integer> TRACK_WIDTH = new Property<RecyclerViewFastScroller, Integer>(Integer.class, "width") { @@ -204,9 +207,9 @@ public class RecyclerViewFastScroller extends View { * Handles the touch event and determines whether to show the fast scroller (or updates it if * it is already showing). */ - public boolean handleTouchEvent(MotionEvent ev) { - int x = (int) ev.getX(); - int y = (int) ev.getY(); + public boolean handleTouchEvent(MotionEvent ev, Point offset) { + int x = (int) ev.getX() - offset.x; + int y = (int) ev.getY() - offset.y; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: // Keep track of the down positions @@ -260,7 +263,6 @@ public class RecyclerViewFastScroller extends View { } private void calcTouchOffsetAndPrepToFastScroll(int downY, int lastY) { - mRv.getParent().requestDisallowInterceptTouchEvent(true); mIsDragging = true; if (mCanThumbDetach) { mIsThumbDetached = true; @@ -358,4 +360,16 @@ public class RecyclerViewFastScroller extends View { mMaxWidth, mRv.getScrollbarTrackHeight() - mMaxWidth - height); mPopupView.setTranslationY(top); } + + public boolean isHitInParent(float x, float y, Point outOffset) { + if (mThumbOffsetY < 0) { + return false; + } + getHitRect(sTempRect); + sTempRect.top += mRv.getScrollBarTop(); + if (outOffset != null) { + outOffset.set(sTempRect.left, sTempRect.top); + } + return sTempRect.contains((int) x, (int) y); + } } diff --git a/src/com/android/launcher3/views/TopRoundedCornerView.java b/src/com/android/launcher3/views/TopRoundedCornerView.java index ba223c498..3ba8ca377 100644 --- a/src/com/android/launcher3/views/TopRoundedCornerView.java +++ b/src/com/android/launcher3/views/TopRoundedCornerView.java @@ -17,12 +17,14 @@ package com.android.launcher3.views; import android.content.Context; import android.graphics.Canvas; +import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.util.AttributeSet; import android.widget.FrameLayout; import com.android.launcher3.R; +import com.android.launcher3.util.Themes; /** * View with top rounded corners. @@ -33,23 +35,41 @@ public class TopRoundedCornerView extends FrameLayout { private final Path mClipPath = new Path(); private float[] mRadii; + private final Paint mNavBarScrimPaint; + private int mNavBarScrimHeight = 0; + public TopRoundedCornerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); int radius = getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius); mRadii = new float[] {radius, radius, radius, radius, 0, 0, 0, 0}; + + mNavBarScrimPaint = new Paint(); + mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor)); } public TopRoundedCornerView(Context context, AttributeSet attrs) { this(context, attrs, 0); } + public void setNavBarScrimHeight(int height) { + if (mNavBarScrimHeight != height) { + mNavBarScrimHeight = height; + invalidate(); + } + } + @Override public void draw(Canvas canvas) { canvas.save(); canvas.clipPath(mClipPath); super.draw(canvas); canvas.restore(); + + if (mNavBarScrimHeight > 0) { + canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(), + mNavBarScrimPaint); + } } @Override diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java index 48f8afecd..b31feed3d 100644 --- a/src/com/android/launcher3/widget/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java @@ -23,7 +23,6 @@ import android.graphics.Rect; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; -import android.view.View; import android.view.animation.AnimationUtils; import com.android.launcher3.Insettable; @@ -31,6 +30,8 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetHost.ProviderChangedListener; import com.android.launcher3.R; +import com.android.launcher3.views.RecyclerViewFastScroller; +import com.android.launcher3.views.TopRoundedCornerView; /** * Popup for showing the full list of available widgets @@ -46,7 +47,6 @@ public class WidgetsFullSheet extends BaseWidgetSheet private final WidgetsListAdapter mAdapter; - private View mNavBarScrim; private WidgetsRecyclerView mRecyclerView; public WidgetsFullSheet(Context context, AttributeSet attrs, int defStyleAttr) { @@ -65,7 +65,6 @@ public class WidgetsFullSheet extends BaseWidgetSheet protected void onFinishInflate() { super.onFinishInflate(); mContent = findViewById(R.id.container); - mNavBarScrim = findViewById(R.id.nav_bar_bg); mRecyclerView = findViewById(R.id.widgets_list_view); mRecyclerView.setAdapter(mAdapter); @@ -91,7 +90,6 @@ public class WidgetsFullSheet extends BaseWidgetSheet public void setInsets(Rect insets) { mInsets.set(insets); - mNavBarScrim.getLayoutParams().height = insets.bottom; mRecyclerView.setPadding( mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), insets.bottom); @@ -100,6 +98,8 @@ public class WidgetsFullSheet extends BaseWidgetSheet } else { clearNavBarColor(); } + + ((TopRoundedCornerView) mContent).setNavBarScrimHeight(mInsets.bottom); requestLayout(); } @@ -195,7 +195,11 @@ public class WidgetsFullSheet extends BaseWidgetSheet // Disable swipe down when recycler view is scrolling if (ev.getAction() == MotionEvent.ACTION_DOWN) { mNoIntercept = false; - if (mLauncher.getDragLayer().isEventOverView(mContent, ev)) { + RecyclerViewFastScroller scroller = mRecyclerView.getScrollbar(); + if (scroller.getThumbOffsetY() >= 0 && + mLauncher.getDragLayer().isEventOverView(scroller, ev)) { + mNoIntercept = true; + } else if (mLauncher.getDragLayer().isEventOverView(mContent, ev)) { mNoIntercept = !mRecyclerView.shouldContainerScroll(ev, mLauncher.getDragLayer()); } } diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java index 89c88a4e7..124058ec4 100644 --- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java +++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java @@ -17,8 +17,12 @@ package com.android.launcher3.widget; import android.content.Context; +import android.graphics.Point; import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.OnItemTouchListener; import android.util.AttributeSet; +import android.view.MotionEvent; import android.view.View; import com.android.launcher3.BaseRecyclerView; @@ -27,13 +31,15 @@ import com.android.launcher3.R; /** * The widgets recycler view. */ -public class WidgetsRecyclerView extends BaseRecyclerView { +public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouchListener { - private static final String TAG = "WidgetsRecyclerView"; private WidgetsListAdapter mAdapter; private final int mScrollbarTop; + private final Point mFastScrollerOffset = new Point(); + private boolean mTouchDownOnScroller; + public WidgetsRecyclerView(Context context) { this(context, null); } @@ -46,6 +52,7 @@ public class WidgetsRecyclerView extends BaseRecyclerView { // API 21 and below only support 3 parameter ctor. super(context, attrs, defStyleAttr); mScrollbarTop = getResources().getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin); + addOnItemTouchListener(this); } public WidgetsRecyclerView(Context context, AttributeSet attrs, int defStyleAttr, @@ -56,7 +63,6 @@ public class WidgetsRecyclerView extends BaseRecyclerView { @Override protected void onFinishInflate() { super.onFinishInflate(); - addOnItemTouchListener(this); // create a layout manager with Launcher's context so that scroll position // can be preserved during screen rotation. setLayoutManager(new LinearLayoutManager(getContext())); @@ -145,4 +151,26 @@ public class WidgetsRecyclerView extends BaseRecyclerView { public int getScrollBarTop() { return mScrollbarTop; } + + @Override + public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { + if (e.getAction() == MotionEvent.ACTION_DOWN) { + mTouchDownOnScroller = + mScrollbar.isHitInParent(e.getX(), e.getY(), mFastScrollerOffset); + } + if (mTouchDownOnScroller) { + return mScrollbar.handleTouchEvent(e, mFastScrollerOffset); + } + return false; + } + + @Override + public void onTouchEvent(RecyclerView rv, MotionEvent e) { + if (mTouchDownOnScroller) { + mScrollbar.handleTouchEvent(e, mFastScrollerOffset); + } + } + + @Override + public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } }
\ No newline at end of file |