coordinatorlayout 中的重叠视图

Posted

技术标签:

【中文标题】coordinatorlayout 中的重叠视图【英文标题】:Overlapping views in coordinatorlayout 【发布时间】:2016-07-02 16:57:08 【问题描述】:

代码如下。当片段加载时,它会覆盖工具栏和我的浮动操作栏。我该如何处理?我希望显示工具栏。 coordinatorlayout 中似乎有一些重叠。我已经检查了这样的不同问题。似乎没有人回答我的问题

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout
    android:layout_
    android:layout_
    android:padding="@dimen/activity_horizontal_margin"
    android:orientation="vertical"
    tools:context="com.example.sammybobo.moglis.MoGLISMaps"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:android="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <android.support.v7.widget.Toolbar
        android:layout_
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_
        android:id="@+id/toolbar"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        android:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

    <android.support.design.widget.FloatingActionButton
        android:id = "@+id/fab"
        android:layout_
        android:layout_
        android:src = "@android:drawable/ic_input_add"
        android:layout_gravity = "bottom|end"
        app:fabSize = "mini">

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

    <fragment
        android:layout_
        android:layout_
        android:id="@+id/main_map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        xmlns:android="http://schemas.android.com/apk/res/android"
        tools:context = "com.example.sammybobo.moglis.MoGLISMaps"
        xmlns:tools="http://schemas.android.com/tools"
        />
 <LinearLayout
        android:layout_
        android:layout_
        android:background="#fff"
        android:layout_gravity = "bottom"
        >
        <Button
            android:layout_
            android:layout_
            android:layout_weight="1"
            android:text="My location"
            android:onClick="observe"/>

        <Button
            android:layout_
            android:layout_
            android:layout_weight="1"
            android:text = "Friends"/>

        <Button
            android:layout_
            android:layout_
            android:layout_weight="1"
            android:text = "settings"/>
    </LinearLayout>
    </android.support.design.widget.CoordinatorLayout>

【问题讨论】:

【参考方案1】:

这是因为在协调器布局中,您无法设置一个视图相对于另一个视图。您只能将它们与父级关联。试试下面的布局。

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:android="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:orientation="vertical"
    android:padding="@dimen/activity_horizontal_margin"
    tools:context="com.example.sammybobo.moglis.MoGLISMaps">

    <RelativeLayout
        android:layout_
        android:layout_>

        <android.support.v7.widget.Toolbar
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            android:elevation="4dp"
            android:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar"/>

        <fragment
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:id="@+id/main_map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_
            android:layout_
            android:layout_below="@+id/toolbar"
            tools:context="com.example.sammybobo.moglis.MoGLISMaps"
            />

    </RelativeLayout>


    <LinearLayout
        android:background="#fff"
        android:layout_gravity="bottom"
        android:layout_
        android:layout_
        >

        <Button
            android:layout_
            android:layout_weight="1"
            android:layout_
            android:onClick="observe"
            android:text="My location"/>

        <Button
            android:layout_
            android:layout_weight="1"
            android:layout_
            android:text="Friends"/>

        <Button
            android:layout_
            android:layout_weight="1"
            android:layout_
            android:text="settings"/>
    </LinearLayout>

    <android.support.design.widget.FloatingActionButton
        app:fabSize="mini"
        android:id="@+id/fab"
        android:layout_gravity="bottom|end"
        android:layout_
        android:layout_
        android:src="@android:drawable/ic_input_add">

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

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

如果您希望底部线性布局也不与片段重叠,则将其放在相对布局中,并确保片段在线性布局上方。

【讨论】:

非常感谢。它有效,但我如何防止相对布局与工具栏重叠 工具栏在相对布局里面。为什么会重叠? 对不起 - 相对布局与晶圆厂重叠。 我已经编辑了我的答案。将晶圆厂布局移至底部。无论底部的哪个布局都将最后绘制,因此它将绘制在已经绘制的相对布局上。您希望晶圆厂位于相对布局之上。 很高兴我能帮上忙。这实际上是一个非常好的主意。会及时通知您。【参考方案2】:

子视图重叠,因为没有设置任何东西来防止重叠。 CoordinatorLayout 的基本布局行为来自FrameLayout,它旨在为其子级提供一块屏幕(即一个框架)。有多个孩子,他们按源顺序堆叠在彼此的前面,从后到前,所以最后一个孩子在前面。这就是为什么片段@id/main_mapLinearLayout 与工具栏@id/toolbar 和浮动操作按钮@id/fab 重叠的原因。

CoordinatorLayouts 自己的,更高级的布局机制是基于用户交互使用Behaviors 动画子布局(稍后会详细介绍)。如果您不使用动画布局,CoordinatorLayout 不是最合适的布局; ConstraintLayoutLinearLayout 之类的可能会更好。这可能是最简单的解决方案:更改布局。以下部分介绍了如果您想要协调行为该怎么做。

行为

如前所述,使用CoordinatorLayout 的主要原因是通过提供视图Behaviors 来为孩子的布局设置动画。当某些依赖视图发生变化时,Behavior 将更新拥有视图的布局。一些小部件具有内置行为,例如FloatingActionButtons 和AppBarLayout。其他人可以通过layout_behavior 属性进行分配,将其设置为要应用的行为的类名。例如,AppBarLayout provides a behavior 将相对于AppBarLayout 偏移滚动视图。此行为最常与折叠工具栏一起使用。例如:

<?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"
    android:layout_
    android:layout_>

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_
        android:layout_>

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_
            android:layout_
            app:toolbarId="@+id/toolbar"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
            app:contentScrim="?attr/colorPrimary"
            >
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_
                android:layout_
                android:layout_gravity="top|fill_horizontal"
                app:layout_insetEdge="top"
                android:fitsSystemWindows="true"
                >
                ...
            </androidx.appcompat.widget.Toolbar>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>
    
    <include layout="@layout/..."
        android:id="@+id/main"
        android:layout_
        android:layout_
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        ...

不存在app:layout_behavior 设置为适当的行为,@id/main 将与 AppBarLayout 重叠。对于某些视图,您还必须设置 layout_widthlayout_height 以防止重叠。

请注意,如果您创建一个新的“基本活动”项目,它将创建类似于上述内容。

来源顺序

如果您希望小部件重叠,但希望在另一个小部件前面使用不同的小部件,请更改源顺序,以便前面的任何小部件都位于它应该覆盖的小部件之后。

重力

如果小部件足够小,您可以将它们沿着不同的边缘打包。使用gravity 将孩子锚定到边缘(例如center|bottomcenter|start)、角落(例如top|endbottom|start)或CoordinatorLayout 的中心。这就是您使用FloatingActionButton 所做的事情:

    <android.support.design.widget.FloatingActionButton
        android:layout_gravity = "bottom|end"
        [...]
        >

您也可以使用例如工具栏来执行此操作。 Buttons 不能这样做,因为重力属性会影响按钮的内容,而不是它的位置。如果您想定位 Button,请将其包裹在(例如)FrameLayoutToolbar 中。确保环绕视图未设置为(显式或隐式)填充父级,例如使用FrameLayouts,否则环绕视图将展开以填充整个框架,从而违背了设置其重力的目的。

    <FrameLayout
        android:layout_
        android:layout_
        android:layout_gravity="top|end"
        ...
        />
        
        <Button
            ...

基于重力的布局来自FrameLayout

闪避

在边缘上定位某些东西后,您可以使用dodgeInsetEdges 将另一个孩子从定位的视图中移开。您还必须在定位的孩子上设置insetEdge,以便可以计算躲避视图的偏移量。请注意,这只会改变视图;它不会调整它的大小,所以如果你试图躲避相反的边缘,它们可能会被抵消。

    <fragment
        app:layout_dodgeInsetEdges="top"
        ...
        />

    <FrameLayout
        android:layout_
        android:layout_
        android:layout_gravity="top|end"
        app:layout_insetEdge="top"
        ...
        />

虽然您可以尝试插入躲避以防止覆盖,但其预期目的是在另一个视图(例如SnackBar)沿边缘进入时将视图移开;插入闪避将为其他视图设置动画,并在新视图进入时将它们滑开。

关键线

您可以使用keylines 水平定位子视图。请注意,如果这样做,您只能使用垂直填充和边距相对于 CoordinatorLayout 顶部垂直定位视图。

锚点

您可以使用锚点将视图定位在另一个视图的边缘。将锚定视图的layout_anchor 设置为要锚定到的视图的ID,以及使用layout_anchorGravity 锚定到视图的哪个部分。

    <fragment
        android:id="@+id/main_map"
        ...
        />
    
    <Button
        app:layout_anchor="@id/main_map"
        app:layout_anchorGravity="top|end"
        ...
        />

【讨论】:

【参考方案3】:

您也可以将所有视图包装在 LinearLayout 中以防止任何重叠。

【讨论】:

【参考方案4】:

CoordinatorLayout 的子级可能有一个。此视图 id 必须对应于 CoordinatorLayout 的任意后代,但它可能不是锚定子本身或锚定子的后代。这可用于相对于其他任意内容窗格放置浮动视图。

孩子可以指定CoordinatorLayout.LayoutParams.insetEdge来描述视图如何插入CoordinatorLayout。 CoordinatorLayout.LayoutParams.dodgeInsetEdges 设置为躲避相同插入边缘的任何子视图将被适当地移动,以使视图不重叠。

<?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"
android:layout_
android:layout_
android:padding="10dp"
xmlns:android="http://schemas.android.com/apk/res/android">

<androidx.appcompat.widget.Toolbar
    android:layout_
    android:layout_
    android:id="@+id/toolbar"
    app:layout_insetEdge="top"
    android:background="@color/teal_500"
    app:title="HOME"
    android:elevation="4dp"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
    android:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>


<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/linearLayoutOptions"
    android:layout_
    android:layout_
    android:background="#fff"
    app:layout_dodgeInsetEdges="top">

    <Button
        android:id="@+id/button5"
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:onClick="observe"
        android:text="My location"
        app:layout_constraintBottom_toBottomOf="@+id/button6"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/button6"
        app:layout_constraintTop_toTopOf="@+id/button6" />

    <Button
        android:id="@+id/button4"
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:text="Friends"
        app:layout_constraintEnd_toStartOf="@+id/button6"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button6"
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:text="settings"
        app:layout_constraintBottom_toBottomOf="@+id/button4"
        app:layout_constraintEnd_toStartOf="@+id/button5"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/button4"
        app:layout_constraintTop_toTopOf="parent" />

    <fragment
        android:id="@+id/mobile_navigation_main"
        android:layout_
        android:layout_
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button6" />

</androidx.constraintlayout.widget.ConstraintLayout>

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id = "@+id/fab"
    android:layout_
    android:layout_
    android:src = "@android:drawable/ic_input_add"
    android:layout_gravity = "bottom|end"
    app:fabSize = "mini"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

【讨论】:

以上是关于coordinatorlayout 中的重叠视图的主要内容,如果未能解决你的问题,请参考以下文章

CoordinatorLayout 内容子项与 BottomNavigationView 重叠

将应用栏滚动视图行为添加到 CoordinatorLayout 中的多个视图

如何用CollapsingToolbar替换CoordinatorLayout中的CardView?

滚动时单击不在 CoordinatorLayout 中的 RecyclerView 上工作

BottomSheetBehavior 该视图不是 CoordinatorLayout 的子视图

如何隐藏 CoordinatorLayout 的一些视图