扩展永久性底片时调整回收者视图的高度

时间:2018-09-11 10:08:21

标签: android user-interface material-design android-coordinatorlayout bottom-sheet

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

展开底页时,我不希望它遮盖回收器视图。我可以通过分别在底部工作表中设置app:layout_insetEdge="bottom"和在回收者视图中设置app:layout_dodgeInsetEdges="bottom"来实现这一目标。

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

相反,我希望回收者视图根据底部纸张的高度动态调整其高度,以使其不再移出屏幕。我该如何实现?

这是完整的布局:

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

5 个答案:

答案 0 :(得分: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,需要编码;
  • 需要进行其他更改以保留原始填充(但仍然可以并且相对容易做到)

答案 1 :(得分:0)

尝试将此属性放入RecyclerView:

app:layout_behavior="@string/appbar_scrolling_view_behavior"

答案 2 :(得分:0)

Nikita接受的答案是正确的主意,但有两个问题:

  • 仅当完全展开底部表单时,建议的填充公式才是正确的,因为作为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的父项进行更改。

请注意,应在布局xml中将RecyclerView的底部页边距设置为底部工作表的窥视高度,以便在加载活动之前获得正确的布局,然后再进行滑动。

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

答案 3 :(得分:-1)

这是整个布局代码,供您参考。我已经尝试通过相应的更改来复制您在问题中提到的相同示例布局。

在floatActionButton的

onClick上,我将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" />

答案 4 :(得分:-1)

您可以做2个解决方案

1是将上边距设置为$timeout(function () { atWhoWrapper.draw(element, atWhoOptions, otherCopyOptions); }, 100);

因为您的CoordinatorLayout未在RecyclerView下对齐RecyclerView。因此,设置上边距Toolbar

actionBarSize

2如果您想android:layout_marginTop="?actionBarSize" 出现RecyclerView

Toolbar设置为android:elevation,因为RecyclerView具有Toolbar高程,并且高于21的版本布局按高程分层。因此设置

4dp

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