简体   繁体   English

由于工具栏,RecycleView在底部留下空白区域

[英]RecycleView leaves empty space at the bottom because of toolbar

Update: 更新:

  • Actual issue is with CoordinatorLayout not with RecycleView . 实际问题是CoordinatorLayout而不是RecycleView
  • Instead of using RecycleView I tried TextView inside ScrollView and it is the same issue. 而不是使用RecycleView我在ScrollView尝试了TextView ,这是同样的问题。
  • Something is not aligned if you have Toolbar as ActionBar and using CoordinatorLayout with another ToolBar as Sticky Header with scrolling element at bottom 如果您将Toolbar作为ActionBar并将CoordinatorLayout与另一个ToolBar一起使用Sticky Header并在底部使用滚动元素,那么就不会对齐某些内容

Original: 原版的:

I'm in process of develop a view which needed Sticky header implementation with recycle view at bottom. 我正在开发一个视图,需要Sticky标头实现,底部有回收视图。 I have used Coordinator layout support as describe here. 我已经使用了协调器布局支持 ,如此处所述。

What is working: 工作原理:

  • Sticky View on scroll list. 滚动列表上的粘滞视图。
    • Toolbar using layout_collapseMode = pin & CollapsingToolbarLayout using layout_scrollFlags = scroll|exitUntilCollapsed|snap property. 工具栏使用layout_collapseMode = pinCollapsingToolbarLayout使用layout_scrollFlags = scroll|exitUntilCollapsed|snap属性。
    • Recycle view with behaviour app:layout_behavior="@string/appbar_scrolling_view_behavior " 使用行为app:layout_behavior="@string/appbar_scrolling_view_behavior回收视图app:layout_behavior="@string/appbar_scrolling_view_behavior

What is issue: 问题是什么:

  • Recycle view leaving margin at bottom, it has same size as Toolbar I'm using to sticky view. 回收视图在底部留下边距,它与我用于粘性视图的Toolbar大小相同。
  • Recycle view last item does not display, it need extra bottom_margin as size of sticky tool bar view. 回收视图最后一项不显示,它需要额外的bottom_margin作为粘性工具栏视图的大小。

Observation: 观察:

  • If I fill recycle instant then it work. 如果我填写回收即时,那么它的工作。 But if notify it with some delay then it causing issue. 但如果通知它有一些延迟,那么它会导致问题。
  • Update. 更新。 In another trial and run**, instead of using Recycle I put an TextView inside the NestedScrollView .(PFA) (not updated in layout here) 在另一个试验和运行**,而不是使用回收我把一个TextView放在NestedScrollView 。(PFA)(这里没有更新布局)
    • Here I have added text from xml and after delay of 2 second just append some more text and it's same result. 这里我添加了xml中的文本,延迟2秒后只需添加一些文本,结果相同。
    • It's layout that take bottom margin again. 它的布局再次降低利润率。 So nothing specific related to Recycle view, it seems some issue with CoordinatorLayout . 所以与Recycle视图没有任何具体关系,看起来与CoordinatorLayout有些问题。

I have tried with multiple solution available here , here , but none of working. 我曾与多个可用的解决方案试图在这里在这里 ,但没有工作。

PFA, current output. PFA,电流输出。

在此输入图像描述

Update PFA, experiment with text view with delay. 更新 PFA,尝试延迟文本视图。

在此输入图像描述

Here is the layout file. 这是布局文件。

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

I believe that the CoordinatorLayout (maybe the AppBarLayout or CollapsingToolbarLayout - not sure which component) is recording the incorrect height of the CollapsingToolbarLayout due to the sticky toolbar. 我相信CoordinatorLayout (可能是AppBarLayoutCollapsingToolbarLayout - 不确定哪个组件)由于粘滞工具栏而记录了CollapsingToolbarLayout的错误高度。 The behavior differs if items are added before or after the initial layout. 如果在初始布局之前或之后添加项,则行为会有所不同。

Try the following: 请尝试以下方法:

  1. Remove android:layout_marginBottom="72dp" from the XML for the RecyclerView . RecyclerView的XML中删除android:layout_marginBottom="72dp"
  2. Add android:minHeight="72dp" to the XML for CollapsingToolbarLayout android:minHeight="72dp"到XML for CollapsingToolbarLayout

Since your sticky toolbar is set at 72dp , it is OK to use minHeight set to 72dp . 由于您的粘性工具栏设置为72dp ,因此可以将minHeight设置为72dp

If you have trouble with this, post back here. 如果您遇到此问题,请回复此处。


Here is a quick demo of your layout using a NestedScrollView and the changes mentioned above. 下面是使用NestedScrollView和上述更改的布局的快速演示。

Update: I have worked this out using RecyclerView which displays the same problem. 更新:我使用RecyclerView解决了这个问题。 Demo project showing the problem and the fix is on GitHub . 演示项目显示问题,修复程序在GitHub上

在此输入图像描述

Here is the code: 这是代码:

MainActivity.java MainActivity.java

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_working.xml activity_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>

activity_not_working.xml 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"
            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:layout_marginBottom="72dp"
        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>

The RecyclerView height is just being calculated wrongfully, when entering scroll. 输入滚动时, RecyclerView高度只是被错误计算。 these two different examples only added confusion to the question, without the least Java code provided. 这两个不同的例子只会增加问题的混淆,而不提供最少的Java代码。

simply remove this one line from the RecyclerView : 只需从RecyclerView删除这一行:

android:layout_marginBottom="72dp"

this attribute has little use, because it's the default value: 此属性几乎没用,因为它是默认值:

android:visibility="visible"

don't set the RecyclerView height like this: 不要像这样设置RecyclerView高度:

android:layout_height="match_parent"

but make it fill up the available space: 但要填补可用空间:

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

so that the RecyclerView would always fit, in case there is a toolbar present, whether or not - this toolbar just shouldn't be set sticky, because this is what demands halfheartedly "fixing" the layout. 因此,如果存在工具栏, RecyclerView将始终适合 - 是否 - 这个工具栏不应该设置为粘性,因为这需要半心半意地“修复”布局。 a BottomNavigationView might eventually be useful there, depending on what that toolbar, might be good for. 一个BottomNavigationView最终可能在那里很有用,这取决于那个工具栏可能有用。 even found the source of the script: CoordinatorBehaviorExample , which should have been attributed, as the license requires it. 甚至找到了脚本的来源: CoordinatorBehaviorExample ,应该被归因,因为许可证需要它。

I assume there could be issue while adding new data and notify adapter. 我假设在添加新数据和通知适配器时可能会出现问题。

You should change from notifyDataSetChanged() to notifyItemInserted(index) . 您应该从notifyDataSetChanged()更改为notifyItemInserted(index)

More documentation on notifyItemInserted(index) here . 这里有关于notifyItemInserted(index)更多文档。

Hope it helps. 希望能帮助到你。

Hey you have set a marginBottom attribute there. 嘿,你在那里设置了marginBottom属性。 Remove that. 删除它。 That's where the error is. 这就是错误所在。 The code for the RecyclerView should be: 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" />

Can you please try the below layout file. 你能试试下面的布局文件吗? I have tested it and it works fine. 我测试了它,它工作正常。 You can remove the marginButtom from the recyclerview as well. 您也可以从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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM