gpt4 book ai didi

android - 如何在 Android 上实现 NestedScrolling?

转载 作者:IT王子 更新时间:2023-10-28 23:40:03 28 4
gpt4 key购买 nike

通过 support-v4 库 22.1.0,android 支持嵌套滚动(android 5.0 之前)。不幸的是,此功能并未真正记录在案。有两个接口(interface)(NestedScrollingParentNestedScrollingChild)以及两个助手委托(delegate)类(NestedScrollingChildHelperNestedScrollingParentHelper)。

有人在 Android 上使用过 NestedScrolling 吗?

我尝试设置一个小例子,我使用 NestedScrollView它同时实现了 NestedScrollingParentNestedScrollingChild

我的布局是这样的:

<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<View
android:id="@+id/header"
android:layout_width="match_parent" android:layout_height="100dp"
android:background="#AF1233"/>

<android.support.v4.widget.NestedScrollView
android:id="@+id/child"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#12AF33"
android:text="@string/long_text"/>

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

</LinearLayout>

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

我想在 NestedScrollView(id = 父级)中显示一个 header view 和另一个 NestedScrollView(id = 子级)。

想法是,通过使用 OnPredrawListener 在运行时调整子 ScrollView 的高度:

public class MainActivity extends Activity {

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

final NestedScrollView parentScroll = (NestedScrollView) findViewById(R.id.parent);
final NestedScrollView nestedScroll = (NestedScrollView) findViewById(R.id.child);
parentScroll.setNestedScrollingEnabled(false);
final View header = findViewById(R.id.header);

parentScroll.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw() {
if (parentScroll.getHeight() > 0) {
parentScroll.getViewTreeObserver().removeOnPreDrawListener(this);
nestedScroll.getLayoutParams().height = parentScroll.getHeight() - 40;
nestedScroll.setLayoutParams(nestedScroll.getLayoutParams());
nestedScroll.invalidate();
return false;
}
return true;
}
});

}
}

所以标题 View 将被部分滚动,40 像素将保持可见,因为我将嵌套子 ScrollView 的高度设置为 parentScroll.getHeight() - 40。好的,在运行时设置高度并滚动父 ScrollView 的工作方式与预期一样(标题滚动出去,40 像素保持可见,然后子 ScrollView 填充标题下方的其余屏幕)。

我希望“NestedScrolling”意味着我可以在屏幕上的任何位置做出滚动手势(父 ScrollView 捕获的触摸事件),并且如果父 ScrollView 已到达末尾,嵌套的子 ScrollView 开始滚动。然而,情况似乎并非如此(简单的滚动手势和滑动手势都不是)。

如果触摸事件从其边界开始,则触摸事件总是由嵌套的子 ScrollView 处理,否则由父 ScrollView 处理。

这是“嵌套滚动”的预期行为还是可以选择更改该行为?

我还尝试用 NestedRecyclerView 替换嵌套的子 ScrollView 。我继承了 RecyclerView 并实现了 NestedScrollingChild 我将所有方法委托(delegate)给 NestedScrollingChildHelper:

public class NestedRecyclerView extends RecyclerView implements NestedScrollingChild {

private final NestedScrollingChildHelper scrollingChildHelper =
new NestedScrollingChildHelper(this);


public void setNestedScrollingEnabled(boolean enabled) {
scrollingChildHelper.setNestedScrollingEnabled(enabled);
}

public boolean isNestedScrollingEnabled() {
return scrollingChildHelper.isNestedScrollingEnabled();
}

public boolean startNestedScroll(int axes) {
return scrollingChildHelper.startNestedScroll(axes);
}

public void stopNestedScroll() {
scrollingChildHelper.stopNestedScroll();
}

public boolean hasNestedScrollingParent() {
return scrollingChildHelper.hasNestedScrollingParent();
}

public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
int dyUnconsumed, int[] offsetInWindow) {

return scrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed,
dyUnconsumed, offsetInWindow);
}

public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return scrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}

public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return scrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}

public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return scrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
}

NestedRecyclerView 根本不滚动。所有的触摸事件都被父 ScrollView 捕获。

最佳答案

我在这上面花了很多时间,只是通过 android 代码试图弄清楚 NestedScrollView 中发生了什么。以下应该可以工作。

public abstract class ParentOfNestedScrollView extends NestedScrollView{

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

/*
Have this return the range you want to scroll to until the
footer starts scrolling I have it as headerCard.getHeight()
on most implementations
*/
protected abstract int getScrollRange();

/*
This has the parent do all the scrolling that happens until
you are ready for the child to scroll.
*/
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed){
if (dy > 0 && getScrollY() < getScrollRange()) {
int oldScrollY = getScrollY();
scrollBy(0, dy);
consumed[1] = getScrollY() - oldScrollY;
}
}

/*
Sometimes the parent scroll intercepts the event when you don't
want it to. This prevents this from ever happening.
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
}

我的一些代码是从这个 question 借来的.从这里我只是根据需要扩展这个类。我的 xml 将 child 作为 NestedScrollView 作为 child ,将 parent 作为 child 。这不能像我想要的那样处理 throw ,这是一项正在进行的工作。

关于android - 如何在 Android 上实现 NestedScrolling?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29885067/

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