随笔博文

setOverScrollMode

2023-03-24 15:41:27 michael007js 187

在 Android 11 及更低版本中,滚动事件会使视觉元素发光。在 Android 12 及更高版本中,发生拖动事件时,视觉元素会拉伸和反弹;发生快速滑动事件时,它们会快速滑动和反弹,新的滚动行为会影响拖动和快速滑动动画。

该行为会应用于使用 EdgeEffect 的所有应用,并且适用于以下类中的所有内容:

视觉效果对垂直滚动和水平滚动都适用。由于它默认应用于未停用滚动的所有应用,因此可以为用户提供更一致的界面体验。

最佳做法

为了确保新的滚动体验与您的应用完美搭配,请遵循以下最佳做法:

拉伸 EdgeEffect 的用法

EdgeEffect 添加了两个用于实现拉伸滚动效果的 API。

float getDistance()
float onPullDistance(float deltaDistance, float displacement)

为了利用拉伸滚动提供最佳用户体验,请执行以下操作:

  • 当用户在释放动画过程中释放并轻触内容时,将轻触注册为“捕捉”。用户停止动画并再次开始操控拉伸。

  • 当用户沿拉伸的相反方向移动手指时,释放拉伸,直到其完全消失,然后开始滚动。

  • 当用户在拉伸过程中快速滑动时,快速滑动 EdgeEffect 以增强拉伸效果。

捕捉动画

当用户捕捉活动的拉伸动画时,EdgeEffect.isFinished() 会返回 false。这表示拉伸应由轻触动作操控。在大多数容器中,这在 onInterceptTouchEvent() 中检测,如以下代码段所示:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
...
 switch (action & MotionEvent.ACTION_MASK) {
   case MotionEvent.ACTION_DOWN:
   ...
     mIsBeingDragged = !mEdgeEffectBottom.isFinished()
         || !mEdgeEffectTop.isFinished();
   ...

在前面的示例中,当 mIsBeingDraggedtrue 时,onInterceptTouchEvent() 返回 true,因此这对于在子级有机会消耗事件之前消耗事件已经足够了。

释放滚动效果

务必在滚动之前释放拉伸效果,以防止将拉伸应用于滚动内容。以下代码示例展示了这一点:


@Override
public boolean onTouchEvent(MotionEvent ev) {

 final int actionMasked = ev.getActionMasked();

 switch (actionMasked) {
   case MotionEvent.ACTION_MOVE:
     final float x = ev.getX(activePointerIndex);
     final float y = ev.getY(activePointerIndex);
     float deltaY = y - mLastMotionY;
     float pullDistance = deltaY / getHeight();
     float displacement = x / getWidth();

     if (deltaY < 0 && mEdgeEffectTop.getDistance() > 0) {
       deltaY -= getHeight() * mEdgeEffectTop
         .onPullDistance(pullDistance, displacement);
   }
     if (deltaY > 0 && mEdgeEffectBottom.getDistance() > 0) {
       deltaY += getHeight() * mEdgeEffectBottom
         .onPullDistance(-pullDistance, 1 - displacement);
   }
         ...

拖动时,在将触摸事件传递给嵌套滚动或拖动滚动内容之前,必须消耗 EdgeEffect 的拉取距离。在前面的代码示例中,当正在显示边缘效果且可以通过动作将其释放时,getDistance() 会返回一个正值。当触摸事件释放拉伸时,它首先由 EdgeEffect 消耗,这样就可以在显示其他效果(如嵌套滚动)之前完全释放。您可以使用 getDistance() 了解释放当前效果所需的拉取距离。

onPullDistance()onPull() 的不同之处在于返回所传递增量的已消耗量。onPull() 以前允许发光效果的总距离为负值。在 Android 12 及更高版本中,如果在 getDistance() 为 0 时向 onPull()onPullDistance() 传递负的 deltaDistance 值,则拉伸不会发生任何变化。

停用

您可以在 XML 布局文件中或以编程方式停用滚动。以下 XML 代码展示了布局文件中设置的 android:overScrollMode

<!-- Via markup -->
<ScrollView
 ...
 android:overScrollMode="never"
 ...
>

以编程方式停用,如以下代码段所示:


<!-- Programmatically-->
...
recyclerview.setOverScrollMode(View.OVER_SCROLL_NEVER);
...


首页
关于博主
我的博客
搜索