我想在我的应用中实现类似iOS的弹跳过卷效果。
我遇到了这个link,它建议创建一个自定义的ScrollView
。但问题是,当我快速上下滚动时,它工作正常,但当我拉屏幕的底部或顶部时,它就卡住了,效果不再起作用。
作为一个例子,我想实现的那种动画,你可以看看这个:
这是我目前拥有的代码:
public class ObservableScrollView extends ScrollView
{
private static final int MAX_Y_OVERSCROLL_DISTANCE = 150;
private Context mContext;
private int mMaxYOverscrollDistance;
public ObservableScrollView(Context context)
{
super(context);
mContext = context;
initBounceScrollView();
}
public ObservableScrollView(Context context, AttributeSet attrs)
{
super(context, attrs);
mContext = context;
initBounceScrollView();
}
public ObservableScrollView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
mContext = context;
initBounceScrollView();
}
private void initBounceScrollView()
{
//get the density of the screen and do some maths with it on the max overscroll distance
//variable so that you get similar behaviors no matter what the screen size
final DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
final float density = metrics.density;
mMaxYOverscrollDistance = (int) (density * MAX_Y_OVERSCROLL_DISTANCE);
}
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent)
{
//This is where the magic happens, we have replaced the incoming maxOverScrollY with our own custom variable mMaxYOverscrollDistance;
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxYOverscrollDistance, isTouchEvent);
}
}
5条答案
按热度按时间eimct9ow1#
我很快就基于
CoordinatorLayout.Behavior
设计了一个简单的解决方案。它并不完美,你也许可以花些时间对它进行微调,但它并不坏。无论如何,结果应该是这样的:在我开始回答这个问题之前,请注意一点:我强烈建议您使用支持库中的
NestedScrollView
而不是普通的ScrollView
。它们在任何方面都是相同的,但是NestedScrollView
在较低的API级别上实现了正确的嵌套滚动行为。无论如何,让我们从我的回答开始:我提出的解决方案适用于任何可滚动容器,无论是
ScrollView
、ListView
还是RecyclerView
,并且不需要子类化任何Views
来实现它。首先,如果您尚未使用Google的设计支持库,则需要将其添加到您的项目中:
请记住,如果您的目标不是API级别25(顺便说一句,您应该这样做),那么您需要包含API级别的最新版本(例如,API级别24的
compile 'com.android.support:design:24.2.0'
)。无论你使用什么样的可滚动容器,都需要在布局中 Package 成
CoordinatorLayout
,在我的例子中,我使用的是NestedScrollView
:CoordinatorLayout
允许你分配一个Behavior
给它的直接子视图。在这个例子中,我们将分配一个Behavior
给NestedScrollView
,NestedScrollView
将实现滚动反弹效果。让我们看一下
Behavior
的代码:解释
Behavior
是什么以及它们是如何工作的超出了这个答案的范围,所以我只想快速解释一下上面的代码是做什么的。Behavior
拦截发生在CoordinatorLayout
的直接子对象中的所有scroll事件。在onStartNestedScroll()
方法中,我们返回true
,因为我们对任何scroll事件都感兴趣。在onNestedScroll()
中,我们查看dyUnconsumed
参数,该参数告诉我们滚动容器没有消耗多少垂直滚动(换句话说,overscroll),然后将滚动容器的子容器平移该量。由于我们只是获取delta值,因此需要在mOverscrollY
变量中对所有delta值求和。onStopNestedScroll()
在滚动事件停止时被调用,这是当我们将滚动容器的所有子容器动画化回到它们的原始位置时。要将
Behavior
赋值给NestedScrollView
,我们需要使用layout_behavior
xml属性,并传入我们要使用的Behavior
的完整类名。在我的示例中,上面的类位于包com.github.wrdlbrnft.testapp
中,因此我必须将com.github.wrdlbrnft.testapp.OverScrollBounceBehavior
设置为值。layout_behavior
是CoordinatorLayout
的自定义属性,因此我们需要使用正确的名称空间作为前缀:注意我在
CoordinatorLayout
上添加的名称空间和NestedScrollView
上添加的app:layout_behavior
属性。这就是你所要做的!虽然这个答案比我预期的要长,但我跳过了一些关于
CoordinatorLayout
和Behaviors
的基础知识。所以如果你不熟悉这些,或者有任何其他问题,请随时提问。kyxcudwk2#
多亏了Xaver Kapeller,我用Kotlin和androidx编写了我的解决方案,覆盖了fling并添加了一些内容
添加协调器依赖项
创建扩展CoordinatorLayout的新类。
使用CoordinatorLayout和NestedScrollView创建XML文件
别忘了加上
字段添加到NestedScrollView XML标记
zrfyljdw3#
如果要使用库,则此**Bouncy**是最符合您要求的最佳库。
mctunoxg4#
这对我来说再合适不过了
滚动装饰-安卓
将以下内容添加到模块的build.gradle文件:
然后导入
现在,您可以使用以下命令设置为任何视图
zlhcx6iw5#
用这个