滚动效果  

您所在的位置:网站首页 安卓页面滚动 滚动效果  

滚动效果  

2023-04-14 23:40| 来源: 网络整理| 查看: 265

在搭载 Android 12 及更高版本的设备上,滚动事件的视觉行为发生了变化。

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

新的滚动行为会影响拖动和快速滑动动画。

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

RecyclerView ListView ScrollView NestedScrollView HorizontalScrollView ViewPager ViewPager2

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

最佳做法

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

适当调整滚动容器的大小,使其子视图能够容纳在边界内。 增加滚动拉伸时,对 EdgeEffect.onPull(deltaDistance, displacement) 中的 deltaDistance 使用正值;减少拉伸时,使用负值。 向下滚动时捕捉动画。 拉伸 EdgeEffect 的用法

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

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

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

当用户在释放动画过程中释放并轻触内容时,将轻触注册为“捕捉”。用户停止动画并再次开始操控拉伸。 当用户沿拉伸的相反方向移动手指时,释放拉伸,直到其完全消失,然后开始滚动。 当用户在拉伸过程中快速滑动时,快速滑动 EdgeEffect 以增强拉伸效果。 捕捉动画

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

Kotlin override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { ... when (action and MotionEvent.ACTION_MASK) { MotionEvent.ACTION_DOWN -> ... isBeingDragged = !edgeEffectBottom.isFinished() || !edgeEffectTop.isFinished() ... } return isBeingDragged } Java @Override public boolean onInterceptTouchEvent(MotionEvent ev) { ... switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: ... mIsBeingDragged = !mEdgeEffectBottom.isFinished() || !mEdgeEffectTop.isFinished(); ...

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

释放滚动效果

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

Kotlin override fun onTouchEvent(ev: MotionEvent): Boolean { val activePointerIndex = ev.actionIndex when (ev.getActionMasked()) { MotionEvent.ACTION_MOVE -> val x = ev.getX(activePointerIndex) val y = ev.getY(activePointerIndex) var deltaY = y - mLastMotionY val pullDistance = deltaY / height val displacement = x / width if (deltaY < 0f && mEdgeEffectTop.distance > 0f) { deltaY -= height * mEdgeEffectTop .onPullDistance(pullDistance, displacement); } if (deltaY > 0f && mEdgeEffectBottom.distance > 0f) { deltaY += height * mEdgeEffectBottom .onPullDistance(-pullDistance, 1 - displacement); } ... } Java @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。

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

Kotlin ... recyclerview.overScrollMode = View.OVER_SCROLL_NEVER ... Java ... recyclerview.setOverScrollMode(View.OVER_SCROLL_NEVER); ... 提供反馈

您的反馈对我们至关重要。如果您发现了问题,或对此功能的改进有自己的见解,请告诉我们。创建新问题前,请先查看现有问题。您可以点击星标按钮,为现有问题投票。

创建新问题

如需了解详情,请参阅问题跟踪器文档。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3