Android 滚动整个屏幕而不是仅滚动列表视图
Android scroll whole screen instead of only listview
我有以下布局结构:
RelativeLayout
-LinearLayout(Vertical)
| ...
| ...
-LinearLayout(Vertical)
ListView
ListView
有一堆由 ArrayAdapter
设置的项目。目前,只有 ListView
是可滚动的,第一个 LinearLayout
留在原处。但是,我希望整个屏幕都可以滚动,所以如果用户滚动得足够远,如果有足够的列表项,ListView
可能会占据整个屏幕。
此图说明了所需的行为(滚动前后)
红框是第一个LinearLayout
,绿框是LinearLayout
和ListView
感谢您宝贵的帮助!
如果您不必使用 RelativeLayout,您可以尝试使用 CoordinatorLayout 的不同结构,如下所示:
<CoordinatorLayout >
<AppBarLayout >
<CollapsingToolbarLayout >
<!-- first layout with the property layout_scrollFlags="scroll" -->
</CollapsingToolbarLayout >
</AppBarLayout >
<ListView > <!-- or RecyclerView to be more updated -->
</CoordinatorLayout >
如果您必须使用 RelativeLayout,您可以选择在 Scrollview 中实现全部(性能不佳并重新发明轮子)或者您可以将视图添加为列表视图的 header
-----为清楚起见编辑这里是我的布局
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="it.italia.playground.CollapseActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:padding="@dimen/padding16"
app:layout_collapseMode="parallax">
<ImageView
android:id="@+id/image"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:maxHeight="@dimen/padding16"
android:scaleType="centerCrop"
android:src="@drawable/img"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/image"
android:layout_centerInParent="true"
android:layout_marginTop="@dimen/padding16"
android:text="text title"
/>
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_layout"></include>
</android.support.design.widget.CoordinatorLayout>
使用适合屏幕的滚动布局并使列表视图包裹内容
正如 wolfy 所说,CoordinatorLayout
是最好的选择,但 ListView
在那种情况下不起作用,因为它没有实现与 [=10= 通信所需的正确回调接口].
CoordinatorLayout
实际上如何协调其子视图的滚动?
您需要为实现 NestedScrollingChild
接口的视图切换 ListView
,您实际上不需要为这些方法编写代码,例如 RecyclerView
或 SwipeRefreshLayout
为您完成这项工作 ;)
然后 CoordinatorLayout
实现了 NestedScrollingParent
接口,这为您节省了另一份工作(google 文档):
This interface should be implemented by ViewGroup subclasses that wish to support scrolling operations delegated by a nested child view.
如果您需要滑动刷新操作,SwipeRefreshLayout
实现了这两个接口。查看视图层次结构,它位于 CoordinatorLayout
和 RecyclerView
之间,因此它可以同时处理 NestedScrollingChild
和 NestedScrollingParent
。
底线:为 RecyclerView
切换 ListView
或使 ListView 实现 NestedScrollingChild
。它应该以任何方式工作!
关于处理新 APi 的滚动的两个极好的解释:
https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout
https://lab.getbase.com/nested-scrolling-with-coordinatorlayout-on-android/
代码 sample,用于实现演示中的 NestedScrollingChild
。
您可以使用 RecyclerView
而不是 ListView
,然后您可以将列表包装在 NestedScrollView
中并调用 ViewCompat.setNestedScrollingEnabled(recyclerView, false)
。在顶部,您可以使用另一个 ScrollView
包含所有内容( 红色标记的视图 在您的图形中)并将那个 NestedScrollView
( 绿色标记的列表)小时候在里面。
NestedScrollView
负责动态设置高度,否则recyclerView只会使用一个固定高度。请注意,如果列表太长,它可能会出现不需要的 UI 滞后,那么通过在列表中展开不同的布局,将所有内容设置为适配器中列表的一部分会更有效。另一方面,这也可能有点棘手,因为整个布局现在是列表的一部分,并且对其所做的所有更改都需要通过适配器。
这是解决方案:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!--here if you want a fab-->
<android.support.design.widget.FloatingActionButton
android:id="@+id/add_edu_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="@dimen/dim_16dp"
android:layout_marginEnd="@dimen/dim_16dp"
app:srcCompat="@drawable/ic_plus_24dp" />
<!--starting the scroll of the layout-->
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--scroll view-->
<RelativeLayout
android:id="@+id/mainScrollChild"
android:layout_width="match_parent"
android:layout_height="0dp">
<!--start adding your red part-->
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_margin="8dp"
android:padding="1dp"/>
<!--end Red Part-->
<!--start the green part (recyclerView)-->
<RelativeLayout
android:id="@+id/rel2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/cardView">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.widget.NestedScrollView>
</RelativeLayout>
<!--end green part-->
</RelativeLayout>
</ScrollView>
</RelativeLayout>
输出:
我有以下布局结构:
RelativeLayout
-LinearLayout(Vertical)
| ...
| ...
-LinearLayout(Vertical)
ListView
ListView
有一堆由 ArrayAdapter
设置的项目。目前,只有 ListView
是可滚动的,第一个 LinearLayout
留在原处。但是,我希望整个屏幕都可以滚动,所以如果用户滚动得足够远,如果有足够的列表项,ListView
可能会占据整个屏幕。
此图说明了所需的行为(滚动前后)LinearLayout
,绿框是LinearLayout
和ListView
感谢您宝贵的帮助!
如果您不必使用 RelativeLayout,您可以尝试使用 CoordinatorLayout 的不同结构,如下所示:
<CoordinatorLayout >
<AppBarLayout >
<CollapsingToolbarLayout >
<!-- first layout with the property layout_scrollFlags="scroll" -->
</CollapsingToolbarLayout >
</AppBarLayout >
<ListView > <!-- or RecyclerView to be more updated -->
</CoordinatorLayout >
如果您必须使用 RelativeLayout,您可以选择在 Scrollview 中实现全部(性能不佳并重新发明轮子)或者您可以将视图添加为列表视图的 header
-----为清楚起见编辑这里是我的布局
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="it.italia.playground.CollapseActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:padding="@dimen/padding16"
app:layout_collapseMode="parallax">
<ImageView
android:id="@+id/image"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:maxHeight="@dimen/padding16"
android:scaleType="centerCrop"
android:src="@drawable/img"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/image"
android:layout_centerInParent="true"
android:layout_marginTop="@dimen/padding16"
android:text="text title"
/>
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_layout"></include>
</android.support.design.widget.CoordinatorLayout>
使用适合屏幕的滚动布局并使列表视图包裹内容
正如 wolfy 所说,CoordinatorLayout
是最好的选择,但 ListView
在那种情况下不起作用,因为它没有实现与 [=10= 通信所需的正确回调接口].
CoordinatorLayout
实际上如何协调其子视图的滚动?
您需要为实现 NestedScrollingChild
接口的视图切换 ListView
,您实际上不需要为这些方法编写代码,例如 RecyclerView
或 SwipeRefreshLayout
为您完成这项工作 ;)
然后 CoordinatorLayout
实现了 NestedScrollingParent
接口,这为您节省了另一份工作(google 文档):
This interface should be implemented by ViewGroup subclasses that wish to support scrolling operations delegated by a nested child view.
如果您需要滑动刷新操作,SwipeRefreshLayout
实现了这两个接口。查看视图层次结构,它位于 CoordinatorLayout
和 RecyclerView
之间,因此它可以同时处理 NestedScrollingChild
和 NestedScrollingParent
。
底线:为 RecyclerView
切换 ListView
或使 ListView 实现 NestedScrollingChild
。它应该以任何方式工作!
关于处理新 APi 的滚动的两个极好的解释:
https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout
https://lab.getbase.com/nested-scrolling-with-coordinatorlayout-on-android/
代码 sample,用于实现演示中的 NestedScrollingChild
。
您可以使用 RecyclerView
而不是 ListView
,然后您可以将列表包装在 NestedScrollView
中并调用 ViewCompat.setNestedScrollingEnabled(recyclerView, false)
。在顶部,您可以使用另一个 ScrollView
包含所有内容( 红色标记的视图 在您的图形中)并将那个 NestedScrollView
( 绿色标记的列表)小时候在里面。
NestedScrollView
负责动态设置高度,否则recyclerView只会使用一个固定高度。请注意,如果列表太长,它可能会出现不需要的 UI 滞后,那么通过在列表中展开不同的布局,将所有内容设置为适配器中列表的一部分会更有效。另一方面,这也可能有点棘手,因为整个布局现在是列表的一部分,并且对其所做的所有更改都需要通过适配器。
这是解决方案:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!--here if you want a fab-->
<android.support.design.widget.FloatingActionButton
android:id="@+id/add_edu_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="@dimen/dim_16dp"
android:layout_marginEnd="@dimen/dim_16dp"
app:srcCompat="@drawable/ic_plus_24dp" />
<!--starting the scroll of the layout-->
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--scroll view-->
<RelativeLayout
android:id="@+id/mainScrollChild"
android:layout_width="match_parent"
android:layout_height="0dp">
<!--start adding your red part-->
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_margin="8dp"
android:padding="1dp"/>
<!--end Red Part-->
<!--start the green part (recyclerView)-->
<RelativeLayout
android:id="@+id/rel2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/cardView">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.widget.NestedScrollView>
</RelativeLayout>
<!--end green part-->
</RelativeLayout>
</ScrollView>
</RelativeLayout>
输出: