无缝嵌套滚动(Android)

无缝嵌套滚动(Android),android,listview,Android,Listview,我们都被建议不要嵌套包含滚动机制的视图。然而,在最新的Android版本(5.0)中,手机应用程序吸引了我的注意力,它似乎是滚动视图中的列表视图 真正让我感兴趣的是,滚动机制从ScrollView无缝切换到ListView 请注意,在实际的ListView开始滚动之前,选项卡上方的内容被推出视图之外 我自己也试过复制,但最终没有成功。这是我采取的基本方法 只需一次连续触摸事件(无需抬起手指) 当用户滚动时,列表视图会慢慢覆盖图像视图。一旦ImageView被100%覆盖并且ListView占据

我们都被建议不要嵌套包含滚动机制的视图。然而,在最新的Android版本(5.0)中,手机应用程序吸引了我的注意力,它似乎是
滚动视图中的
列表视图

真正让我感兴趣的是,滚动机制从
ScrollView
无缝切换到
ListView

请注意,在实际的
ListView
开始滚动之前,选项卡上方的内容被推出视图之外

我自己也试过复制,但最终没有成功。这是我采取的基本方法

只需一次连续触摸事件(无需抬起手指)

当用户滚动时,
列表视图
会慢慢覆盖
图像视图
。一旦
ImageView
被100%覆盖并且
ListView
占据整个屏幕,则
ListView
开始滚动

我当前正在收听
列表视图上的触摸事件,如果已到达顶部,请在
列表视图上调用
RequestDisableWinterCeptTouchEvent
,即

@Override
public boolean onTouch(View v, MotionEvent event) {
  if (listViewAtTop) {
    v.requestDisallowInterceptTouchEvent(true);
  } else {
    v.requestDisallowInterceptTouchEvent(false);
  }
  return false;
}
只有当您抬起手指并继续滚动时,切换滚动上下文才有效


有没有一种不同的方法可以达到预期的效果?

我找到了另一种非常简单的“技巧”。。。仅使用添加了透明标题的
列表视图。

Android 5.0棒棒糖(API 21)添加了嵌套滚动支持

据我所知,ListView(AbsListView)和ScrollView现在都支持此功能(如果在API 21上运行),但必须在滚动视图上启用它

有两种方法,打电话 或者使用布局属性android:nestedScrollingEnabled=“true”(未记录)

要了解其工作原理,或支持自定义小部件,关键方法如下:


不幸的是,除了JavaDoc本身,没有任何指南或培训来解释它是如何工作的,JavaDoc本身非常轻巧,除了ScrollView之外,没有其他示例。

当我试图自己解决这个问题时,我首先发现了这个问题;然而,答案并没有涉及太多细节。我确实找到了很多好的资源,所以如果有人发现自己在寻找这些资源,我会在下面链接它们。这种效果的一个术语是“粘性滚动”


一篇关于“同步滚动”的文章


一个很好的视频展示了一些Android的滚动技巧,“快速返回”和“粘性滚动”

代码:


最后,这里是另一个使用listView而不是ScrollView显示相同效果的示例

代码:
我也一直想达到同样的效果。我在GitHub中找到了一个名为ObserviceScrollView的相关库,它需要通过TouchInterceptFramework在后端做更多的工作,但至少它完成了这项工作,即使对于棒棒糖前的设备也是如此。它不仅支持子ScrollView和ListView,还支持recyclerviews。以下是链接:


我希望他们能把棒棒糖和棒棒糖设备的嵌套滚动作为他们设计标准的一部分。这是一个好迹象。

将最新的支持包com.android.support:support-v4:22.1.1添加到您的项目中。试试这个:

<android.support.v4.widget.NestedScrollView
        android:id="@+id/nScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

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


默认情况下,启用嵌套滚动。

这是虚拟布局的经典示例。乍一看不太明显的东西。基本上情况是这样的

灰色区域->框架布局 然后是填充整个框架布局的listview,然后是与listview上半部分重叠的imageview。listview的第一项是虚拟项,其高度与imageview的高度相同。 (注:实际数据从第二个元素开始)

下一步很容易 根据listview的滚动来翻译Imageview


我认为这是避免嵌套滚动的最佳方法,您可以在
列表视图中使用以下属性组合来实现这一点:

<ImageView ... /> <!-- must be before ListView -->

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="..." <!-- height of imageView -->
    android:clipToPadding="false"
    ...
/>


我用的是这样的东西,我想效果不错

scrollView.onScroll { x, y ->
            Timber.d("ScrollView offset: ($x, $y)")

            val height = dashboardChart.measuredHeight
            val recyclerView =  viewPager.findViewById<RecyclerView>(R.id.recyclerView)
            if(y >= height) {
                Timber.d("ScrollView enable nested scrolling!")
                recyclerView.isNestedScrollingEnabled = true
            } else {
                Timber.d("ScrollView disable nested scrolling!")
                recyclerView.isNestedScrollingEnabled = false
            }
        }
scrollView.onScroll{x,y->
Timber.d(“滚动视图偏移量:($x,$y)”)
val高度=仪表板图表。测量高度
val recyclerView=viewPager.findViewById(R.id.recyclerView)
如果(y>=高度){
d(“ScrollView启用嵌套滚动!”)
recyclerView.isNestedScrollingEnabled=true
}否则{
d(“ScrollView禁用嵌套滚动!”)
recyclerView.isNestedScrollingEnabled=false
}
}

其中scrollView是父级,我正在侦听onScroll事件(它是viewTreeObserver.addOnScrollListener下面的扩展)。然后,根据是否已滚动初始偏移量,我将启用/禁用child recyclerView(类似于ListView或其他滚动视图)滚动。

ListView没有以这种方式填充其高度的问题如何?@Whizzkey。。尝试将android:fillViewport=“true”添加到滚动视图中。