gpt4 book ai didi

java - iOS 喜欢 Android 上的滚动效果

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:51:09 25 4
gpt4 key购买 nike

我想在我的应用中实现类似 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);
}
}

最佳答案

我已经根据 CoordinatorLayout.Behavior 快速组合了一个简单的解决方案。它并不完美,您也许可以花一些时间对其进行微调,但还不错。无论如何,结果应该是这样的:

enter image description here

作为开始回答之前的一个小旁注:我强烈建议您使用支持库中的 NestedScrollView 而不是普通的 ScrollView。它们在任何方面都是相同的,但 NestedScrollView 在较低的 API 级别上实现了正确的嵌套滚动行为。

无论如何,让我们从我的答案开始:我想出的解决方案适用于任何可滚动的容器,无论是 ScrollViewListView 还是 RecyclerView 并且您不需要子类化任何 Views 来实现它。

如果您尚未使用 Google 的设计支持库,首先需要将它添加到您的项目中:

compile 'com.android.support:design:25.0.1'

请记住,如果您的目标不是 API 级别 25(顺便说一句,您应该这样做),那么您需要包含适合您的 API 级别的最新版本(例如,compile 'com.android.support:design: 24.2.0' 用于 API 级别 24)。

无论您使用的是什么可滚动容器,都需要在您的布局中包裹在 CoordinatorLayout 中。在我的示例中,我使用的是 NestedScrollView:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">

<!-- content -->

</android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

CoordinatorLayout 允许您将Behavior 分配给它的直接 subview 。在这种情况下,我们将向 NestedScrollView 分配一个 Behavior,它将实现滚动弹跳效果。

让我们来看看Behavior的代码:

public class OverScrollBounceBehavior extends CoordinatorLayout.Behavior<View> {

private int mOverScrollY;

public OverScrollBounceBehavior() {
}

public OverScrollBounceBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
mOverScrollY = 0;
return true;
}

@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
if (dyUnconsumed == 0) {
return;
}

mOverScrollY -= dyUnconsumed;
final ViewGroup group = (ViewGroup) target;
final int count = group.getChildCount();
for (int i = 0; i < count; i++) {
final View view = group.getChildAt(i);
view.setTranslationY(mOverScrollY);
}
}

@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
final ViewGroup group = (ViewGroup) target;
final int count = group.getChildCount();
for (int i = 0; i < count; i++) {
final View view = group.getChildAt(i);
ViewCompat.animate(view).translationY(0).start();
}
}
}

解释什么是 Behavior 以及它们如何工作超出了这个答案的范围,所以我将快速解释上面代码的作用。 Behavior 拦截在 CoordinatorLayout 的直接子级中发生的所有滚动事件。在 onStartNestedScroll() 方法中,我们返回 true,因为我们对任何滚动事件都感兴趣。在 onNestedScroll() 中,我们查看 dyUnconsumed 参数,它告诉我们有多少垂直滚动没有被滚动容器消耗(换句话说过度滚动),然后翻译滚动容器的子元素。由于我们只是获取增量值,因此我们需要在 mOverscrollY 变量中汇总所有这些值。 onStopNestedScroll() 在滚动事件停止时被调用。这是我们将滚动容器的所有子元素动画化回其原始位置的时候。

要将 Behavior 分配给 NestedScrollView,我们需要使用 layout_behavior xml 属性并传入 的完整类名>Behavior 我们要使用。在我的示例中,上面的类位于包 com.github.wrdlbrnft.testapp 中,因此我必须将 com.github.wrdlbrnft.testapp.OverScrollBounceBehavior 设置为值。 layout_behaviorCoordinatorLayout 的自定义属性,因此我们需要在其前面加上正确的命名空间:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.github.wrdlbrnft.testapp.OverScrollBounceBehavior">

<!-- content -->

</android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

请注意我在 CoordinatorLayout 上添加的命名空间和在 NestedScrollView 上添加的 app:layout_behavior 属性。

这就是您要做的一切!虽然这个答案比我预期的要长,但我跳过了一些关于 CoordinatorLayoutBehaviors 的基础知识。因此,如果您不熟悉这些内容或有任何其他问题,请随时提出。

关于java - iOS 喜欢 Android 上的滚动效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40758635/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com