soc*_*qwe 55 android android-appcompat
使用support-v4库22.1.0 android支持嵌套滚动(pre android 5.0).不幸的是,这个功能并没有真正记录.有两个接口(NestedScrollingParent和NestedScrollingChild)以及两个辅助委托类(NestedScrollingChildHelper和 NestedScrollingParentHelper).
有没有人在Android上使用NestedScrolling?
我尝试设置一个小例子,我使用NestedScrollView实现两者NestedScrollingParent和NestedScrollingChild.
我的布局看起来像这样:
<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>
Run Code Online (Sandbox Code Playgroud)
我想在(id = parent)中显示a header view和另一个NestedScrollView(id = child NestedScrollView).
我们的想法是,在运行时使用以下方法调整子滚动视图的高度OnPredrawListener:
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;
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
因此,标题视图将部分滚动,因为我将嵌套子滚动视图的高度设置为,所以仍然可以看到40个像素parentScroll.getHeight() - 40.好吧,在运行时设置高度并滚动父滚动视图就像预期的那样工作(标题滚出,40个像素保持可见,然后子滚动视图填充标题下面的屏幕的其余部分).
我希望"NestedScrolling"意味着我可以在屏幕上的任何地方做出滚动手势(由父滚动视图捕获的触摸事件),如果父滚动视图已到达结尾,则嵌套的子滚动视图开始滚动.然而,似乎并非如此(简单的滚动手势和投掷手势都不是).
如果触摸事件在其边界开始,则触摸事件始终由嵌套的子scrollview处理,否则由父卷轴视图处理.
这是"嵌套滚动"的预期行为还是有改变该行为的选项?
我还尝试用a替换嵌套的子滚动视图NestedRecyclerView.我将所有方法委托给我的子类RecyclerView和实现:NestedScrollingChildNestedScrollingChildHelper
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);
}
}
Run Code Online (Sandbox Code Playgroud)
但NestedRecyclerView根本不滚动.父滚动视图捕获所有触摸事件.
我花了相当多的时间来检查 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;
}
}
Run Code Online (Sandbox Code Playgroud)
我的一些代码是从这个问题借来的。从这里我只是根据需要扩展这个类。我的 xml 将子级作为 NestedScrollView 作为子级,将父级作为这样。这并不能像我希望的那样处理猛击,这是一项正在进行的工作。
| 归档时间: |
|
| 查看次数: |
14771 次 |
| 最近记录: |