在展开持久性底部工作表时调整回收器视图高度

问题描述 投票:3回答:5

我有一个持久的底部工作表(基本上是一个按钮)和一个包含在CoordinatorLayout中的回收者视图。

当底部页面展开时,我不希望它模糊回收者视图。我可以通过分别在回收器视图中设置底部工作表中的app:layout_insetEdge="bottom"app:layout_dodgeInsetEdges="bottom"来实现此目的。

但是,由于回收者视图的高度设置为android:layout_height="match_parent",因此当底部纸张展开时,其顶部部分移出屏幕。

相反,我希望recyclerview根据底部纸张的高度动态调整其高度,使其不再移出屏幕。我怎样才能做到这一点?

这是完整的布局:

<?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.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:nestedScrollingEnabled="false"
    app:layout_dodgeInsetEdges="bottom" />

<Button
    android:id="@+id/bottom_sheet"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/update_all"
    android:foreground="?attr/selectableItemBackground"
    android:background="@drawable/angled_button"
    app:behavior_hideable="false"
    app:behavior_peekHeight="0dp"
    app:layout_insetEdge="bottom"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior" />

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

编辑:添加了屏幕截图

没有底板,一切看起来都很好。 enter image description here

随着底板的扩展,再循环器视图不再完全可见。 enter image description here

编辑2:GIF添加

enter image description here

android user-interface material-design android-coordinatorlayout bottom-sheet
5个回答
4
投票

最近面临同样的问题,没有找到比删除app:layout_dodgeInsetEdges="bottom"更好的方法,而是使用填充。这是如何实现的:

科特林:

val rv = findViewById<RecyclerView>(R.id.recycler_view))
val behavior = BottomSheetBehavior.from(findViewById<Button>(R.id.bottom_sheet))
behavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback(){
    override fun onSlide(bottomSheet: View, offset: Float) {
        rv.setPadding(0, 0, 0, (bottomSheet.height * offset).toInt())
    }

    override fun onStateChanged(bottomSheet: View, newState: Int){}
})

Java的:

RecyclerView rv = (RecyclerView) findViewById(R.id.recycler_view); 
BottomSheetBehavior behavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet));
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
    @Override
    public void onStateChanged(@NonNull View bottomSheet, int newState) {
    }

    @Override
    public void onSlide(@NonNull View bottomSheet, float slideOffset) {
        rv.setPadding(0, 0, 0, (int)(slidingView.getHeight() * offset));
    }
});

优点:

  • 屏幕上没有重叠,既没有工具栏也没有BottomSheet按钮;
  • 不会破坏FAB的上移功能;
  • RecyclerView滚动可以与BottomSheet一起向上滑动;

缺点:

  • 不是纯XML,需要编码;
  • 需要进行其他更改以保持原始填充(但仍然可以并且相对容易)

0
投票

尝试将此属性放入RecyclerView:

app:layout_behavior="@string/appbar_scrolling_view_behavior"

0
投票

尼基塔接受的答案有正确的想法,但有两个问题:

  • 建议的填充公式仅在底部图纸完全展开时才是正确的,因为作为onSlide回调的参数提供的slideOffset与峰值高度和底部图纸的完整高度之间的差异成比例,而不仅仅是其全高度
  • 填充不适用于recyclerview的快速滚动条,该滚动条继续在底部工作表下方延伸。另一方面,保证金的行为符合预期。

这是一个Kotlin实现,它考虑了这两个更正:

val behavior = BottomSheetBehavior.from(constraintLayout)
behavior.setBottomSheetCallback(object : BottomSheetCallback() {

    override fun onSlide(bottomSheet: View, slideOffset: Float) {
        val margin = behavior.peekHeight + (bottomSheet.height - behavior.peekHeight) * slideOffset
        recyclerview.updateLayoutParams<FrameLayout.LayoutParams> { bottomMargin = margin.toInt() }
    }

    override fun onStateChanged(bottomSheet: View, newState: Int) { /* Nothing to do */ }
})

引用的LayoutParams类型应根据您自己布局中的RecyclerView的父级进行更改。

请注意,RecyclerView的下边距应设置为布局xml中底部工作表的峰值高度,以便在活动加载之前,在任何滑动发生之前获得正确的布局。

上面的示例是针对不可隐藏的底部工作表,这意味着slideOffset参数仅从0到1.对于可隐藏的底部工作表,当slideOffset介于-1和0之间时,应使用另一个公式:behavior.peekHeight * (1 + slideOffset)


-1
投票

You can do 2 solutions

1 is to set top-margin to RecyclerView

因为你的CoordinatorLayout没有在RecyclerView下方对齐Toolbar。所以设置顶部边缘actionBarSize

android:layout_marginTop="?actionBarSize"

2 If you want RecyclerView comes up of Toolbar

android:elevation设置为RecyclerView因为Toolbar具有4dp高程,并且21个以上的版本布局按高程分层。所以设定

<android.support.v7.widget.RecyclerView
    ...
    android:elevation="@dimen/design_appbar_elevation"/>

design_appbar_elevation值是16dp


-1
投票

这是整个布局代码供您参考。我试图通过相应的更改复制您在问题中提到的相同样本布局。

onClick的floatActionButton,我将bottom_sheet的状态更改为BottomSheetBehavior.STATE_EXPANDED。复制行为

<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">

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

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_animal_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:nestedScrollingEnabled="false"
        app:layout_dodgeInsetEdges="bottom" />

</LinearLayout>

<android.support.design.widget.FloatingActionButton
    android:id="@+id/add_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="16dp" />

<Button
    android:id="@+id/bottom_sheet"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:foreground="?attr/selectableItemBackground"
    android:text="Update all"
    app:behavior_hideable="false"
    app:behavior_peekHeight="0dp"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
    app:layout_insetEdge="bottom" />

© www.soinside.com 2019 - 2024. All rights reserved.