在 Coordinator Layout 中定位视图

14

我正在尝试创建一个包含以下内容的协调布局屏幕:

  • 工具栏
  • 片段,将使用导航API为每个页面替换
  • 底部应用程序栏

然而,我在以一种方式定位视图方面遇到了困境,使得应用程序的底部栏不会重叠在片段中。

请问你能帮我解决这个问题吗?据我所知,唯一的方法是在底部添加边距,但这可能在设备之间不一致。

为了说明,此列表共有25个项目,但最后两个项目被应用程序的底部栏所覆盖。

输入图像描述

主活动

<?xml version="1.0" encoding="utf-8"?>
<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"
        tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/app_bar_layout"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/AppTheme.AppBarOverlay"
            android:animateLayoutChanges="true"
            android:layout_above="@id/include">

        <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>

        <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

            <com.google.android.material.tabs.TabItem
                    android:text="Test 1"
                    android:layout_height="match_parent"
                    android:layout_width="match_parent"/>

            <com.google.android.material.tabs.TabItem
                    android:text="Test 2"
                    android:layout_height="match_parent"
                    android:layout_width="match_parent"/>
        </com.google.android.material.tabs.TabLayout>

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

    <include
            layout="@layout/content_main"
            android:id="@+id/include"/>

    <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bar"
            android:layout_gravity="bottom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_anchorGravity="right|top"
            app:layout_anchor="@+id/bar"
            android:src="@drawable/ic_add_black_24dp"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

内容主要xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
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"
tools:showIn="@layout/activity_main"
tools:context=".MainActivity">

    <fragment
            android:layout_width="411dp"
            android:layout_height="627dp"
            android:name="com.example.fitnessfatality.startScreen.StartFragment"
            android:id="@+id/fragment"
            />

</FrameLayout>

为什么不使用ConstraintLayout呢? - Andrey Busik
我考虑使用约束布局,但是带有固定FAB的底部应用栏只能与约束布局一起使用。一旦找到解决此问题的方法,我还想学习如何实现滚动行为。 - Jeremi
找到了吗?我也遇到了同样的问题,只有单帧布局。 - ateebahmed
请使用android:layout_marginBottom="?attr/actionBarSize"或bottomPadding和cliptopadding="false",可以从导航栏顶部获取填充值。 - Richard Muvirimi
2个回答

11
请使用以下3个属性来定位元素。
android:layout_gravity=""
app:layout_anchorGravity=""
app:layout_anchor="@id/xxxx"

这里也有一个完整的 XML ,可以帮助您

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".home.HomeFragment">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:fitsSystemWindows="true"
        android:id="@+id/app_barlayout"
        android:theme="@style/AppTheme.AppBarOverlay">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collaps_toolabar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
            app:expandedTitleTextAppearance="@style/CollapsingToolbarLayoutExpandedTextStyle">
            <LinearLayout
                android:id="@+id/layout_currentMatch_item"
                android:layout_width="match_parent"
                android:layout_height="160dp"
                android:orientation="vertical">


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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:layout_anchorGravity="bottom"
        app:layout_anchor="@id/app_barlayout"
        android:orientation="horizontal" />

   

</androidx.coordinatorlayout.widget.CoordinatorLayout>

4
您可以在CoordinatorLayout内使用LinearLayout来安排视图,如果符合您的需要,也可以使用ConstraintLayout。
我希望决策的基础清晰明了。请看这个例子:
<?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"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>

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

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

        <include
                layout="@layout/content_main"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"/>

        <LinearLayout
                android:id="@+id/bar"
                android:orientation="vertical"
                android:layout_weight="0"
                android:background="@color/colorAccent"
                android:layout_width="match_parent"
                android:layout_height="100dp"/>
    </LinearLayout>

    <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="@dimen/fab_margin"
            app:srcCompat="@android:drawable/ic_dialog_email"/>

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

enter image description here


谢谢您的建议。这是一个可行的解决方案,但它没有利用底部应用栏并失去了它所带来的好效果 :) 我可能会在滚动时隐藏底部栏以避免这个问题。 - Jeremi
@Jeremi,什么时候应该显示底部栏?只有当你完全向下滚动列表时才会显示吗? - Andrey Busik
还是底部栏的行为类似于 Snackbar? - Andrey Busik
我想始终显示底部栏,只在滚动时隐藏选项卡布局。 - Jeremi
我刚刚成功地实现了向下滚动时隐藏底部应用栏,向上滚动时再次显示它 :) 这有一个非常令人愉悦的效果,只需要添加bar.hideOnScroll = true。我认为最好添加一些额外的底部填充,以防列表中没有足够的项目可以滚动,否则某些项目可能仍然不可见。 - Jeremi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接