RecycleView由于工具栏而在底部留有空白空间

时间:2019-03-01 07:26:30

标签: android android-toolbar android-coordinatorlayout android-collapsingtoolbarlayout stickyrecycleview

更新:

  • 实际问题出在CoordinatorLayout而不是RecycleView上。
  • 我没有在RecycleView内尝试TextView,而是使用ScrollView,这是同样的问题。
  • 如果您将Toolbar设置为ActionBar,并且将CoordinatorLayout与另一个ToolBar用作粘性标题,并且滚动元素在底部,则无法对齐

原始

我正在开发一个视图,该视图需要粘滞头实现并在底部使用回收视图。我已经使用Coordinator layout support进行了描述。

工作原理:

  • 滚动列表上的粘滞视图。
    • 使用 layout_collapseMode = pin 的工具栏和使用{strong> CollapsingToolbarLayout 属性的layout_scrollFlags = scroll|exitUntilCollapsed|snap的工具栏。
    • 以行为 app:layout_behavior="@string/appbar_scrolling_view_behavior
    • 回收视图

问题是什么

  • 回收视图,将边距留在底部,其大小与我用来粘贴视图的Toolbar相同。
  • 回收视图最后一项没有显示,它需要额外的 bottom_margin 作为粘性工具栏视图的大小。

观察:

  • 如果我填满回收站,那么它可以工作。但是如果延迟通知它会导致问题。
  • 更新。在另一次试用运行中,我没有在TextView(PFA)中放置NestedScrollView。(PFA)(此处未在布局中更新)
    • 在这里,我从xml中添加了文本,延迟2秒后,仅追加了一些文本,结果相同。
    • 这种布局再次占据了页边空白。因此,与回收视图无关,CoordinatorLayout似乎存在一些问题。

我尝试了多种可用的解决方案herehere,但没有用。

PFA,当前输出。

enter image description here

更新 PFA,尝试延迟文本视图。

enter image description here

这是布局文件。

<androidx.coordinatorlayout.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">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/summaryAppBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/main.collapsing"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="256dp"
                android:background="@drawable/fable_1"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.3" />

            <!-- This is sticky header-->
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/summaryToolBar"
                android:layout_width="match_parent"
                android:layout_height="72dp"
                android:layout_gravity="center"
                android:background="@android:color/white"
                android:padding="@dimen/common_layout_margin"
                android:visibility="visible"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textSize="24sp"
                        android:text="Name" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="right"
                        android:textSize="24sp"
                        android:text="Offer"/>

                </FrameLayout>

            </androidx.appcompat.widget.Toolbar>

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

   <!-- Bottom margin if I do't use then it does not display last child item. Wired but true in this case-->

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:visibility="visible"
        android:layout_marginBottom="72dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:listItem="@layout/item_dessert" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

5 个答案:

答案 0 :(得分:5)

我认为CoordinatorLayout(也许是AppBarLayoutCollapsingToolbarLayout-不确定哪个组件)由于工具栏的粘性而记录了CollapsingToolbarLayout的不正确高度。如果在初始布局之前或之后添加项目,则行为会有所不同。

尝试以下操作:

  1. 从XML中删除android:layout_marginBottom="72dp"的{​​{1}}。
  2. RecyclerView添加到android:minHeight="72dp"的XML中

由于粘性工具栏设置为CollapsingToolbarLayout,因此可以将72dp设置为minHeight

如果对此有疑问,请发回此处。


以下是使用72dp和上述更改的布局快速演示。

更新:我已经使用NestedScrollView来解决了这个问题,该问题显示了相同的问题。显示问题和修复程序的演示项目位于GitHub

enter image description here

代码如下:

MainActivity.java

RecyclerView

activity_working.xml

public class MainActivity extends AppCompatActivity {  
    // Set to true to break the layout; false for it to work.  
    // The setting of this flag should only matter for the 
    // layout activity_not_working.  
    private boolean mBreakIt = true;  

    //    private int mLayoutToUse = R.layout.activity_not_working;  
    private int mLayoutToUse = R.layout.activity_working;  

    private LinearLayout mLayout;  

    @Override  
  protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(mLayoutToUse);  

        mLayout = findViewById(R.id.linearLayout);  
        if (mBreakIt) {  
            mLayout.post(new Runnable() {  
                @Override  
  public void run() {  
                    addViews();  
                }  
            });  
        } else {  
            addViews();  
        }  
    }  

    private void addViews() {  
        for (int i = 0; i < 50; i++) {  
            TextView tv = new TextView(MainActivity.this);  
            tv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,  
                    ViewGroup.LayoutParams.WRAP_CONTENT));  
            tv.setText("TextView #" + (i + 1));  
            mLayout.addView(tv);  
        }  
    }  
}

activity_not_working.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/summaryAppBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/main.collapsing"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="72dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="256dp"
                android:background="@drawable/beach"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.3" />

            <!-- This is sticky header-->
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/summaryToolBar"
                android:layout_width="match_parent"
                android:layout_height="72dp"
                android:layout_gravity="center"
                android:background="@android:color/white"
                android:padding="@dimen/common_layout_margin"
                android:visibility="visible"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Name"
                        android:textSize="24sp" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="right"
                        android:text="Offer"
                        android:textSize="24sp" />

                </FrameLayout>

            </androidx.appcompat.widget.Toolbar>

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <!-- Bottom margin if I do't use then it does not display last child item. Wired but true in this case-->
    <!-- Removed following: -->
    <!--android:layout_marginBottom="72dp"-->

    <androidx.core.widget.NestedScrollView
        android:id="@+id/nestedScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_blue_light"
        android:visibility="visible"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:layout_insetEdge="bottom"
        tools:listItem="@layout/item_dessert">

        <LinearLayout
            android:id="@+id/linearLayout"
            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:text="A TextView" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="A TextView" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="A TextView" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="A TextView" />


        </LinearLayout>
    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

答案 1 :(得分:4)

输入滚动条时,RecyclerView高度的计算错误。这两个不同的示例仅使问题更加混乱,而没有提供最少的Java代码。

只需从RecyclerView中删除这一行:

android:layout_marginBottom="72dp"

此属性几乎没有用,因为它是默认值:

android:visibility="visible"

请勿像这样设置RecyclerView高度:

android:layout_height="match_parent"

但要使其填充可用空间:

android:layout_height="0dp"
android:layout_weight="1.00"

,以确保RecyclerView始终适合存在的工具栏,无论该工具栏是否设置为粘滞,因为这需要全心全意地“固定”布局。 BottomNavigationView最终可能在那里有用,具体取决于该工具栏的用途。甚至找到了脚本的来源:CoordinatorBehaviorExample,根据许可证的要求,应该将其归属。

答案 2 :(得分:3)

我认为添加新数据并通知适配器时可能会出现问题。

您应该从notifyDataSetChanged()更改为notifyItemInserted(index)

有关notifyItemInserted(index) here的更多文档。

希望有帮助。

答案 3 :(得分:2)

嘿,您在那里设置了marginBottom属性。删除它。那就是错误所在。 RecyclerView的代码应为:

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:listItem="@layout/item_dessert" />

答案 4 :(得分:2)

能否请您尝试以下布局文件。我已经对其进行了测试,并且效果很好。您也可以从recyclerview中删除marginButtom。         

xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">


<androidx.coordinatorlayout.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">

<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/summaryAppBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.appbar.CollapsingToolbarLayout
        android:id="@+id/main.collapsing"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:background="@drawable/fable_1"
            app:layout_collapseMode="parallax"
            app:layout_collapseParallaxMultiplier="0.3" />

        <!-- This is sticky header-->
        <androidx.appcompat.widget.Toolbar
            android:id="@+id/summaryToolBar"
            android:layout_width="match_parent"
            android:layout_height="72dp"
            android:layout_gravity="center"
            android:background="@android:color/white"
            android:padding="@dimen/common_layout_margin"
            android:visibility="visible"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="24sp"
                    android:text="Name" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="right"
                    android:textSize="24sp"
                    android:text="Offer"/>

            </FrameLayout>

        </androidx.appcompat.widget.Toolbar>

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>



    <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:visibility="visible"
    android:layout_marginBottom="72dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:listItem="@layout/item_dessert" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>