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_map
和LinearLayout
与工具栏@id/toolbar
和浮动操作按钮@id/fab
重叠的原因。
CoordinatorLayout
s 自己的,更高级的布局机制是基于用户交互使用Behavior
s 动画子布局(稍后会详细介绍)。如果您不使用动画布局,CoordinatorLayout
不是最合适的布局; ConstraintLayout
或 LinearLayout
之类的可能会更好。这可能是最简单的解决方案:更改布局。以下部分介绍了如果您想要协调行为该怎么做。
行为
如前所述,使用CoordinatorLayout
的主要原因是通过提供视图Behavior
s 来为孩子的布局设置动画。当某些依赖视图发生变化时,Behavior
将更新拥有视图的布局。一些小部件具有内置行为,例如FloatingActionButton
s 和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_width
和 layout_height
以防止重叠。
请注意,如果您创建一个新的“基本活动”项目,它将创建类似于上述内容。
来源顺序
如果您希望小部件重叠,但希望在另一个小部件前面使用不同的小部件,请更改源顺序,以便前面的任何小部件都位于它应该覆盖的小部件之后。
重力
如果小部件足够小,您可以将它们沿着不同的边缘打包。使用gravity 将孩子锚定到边缘(例如center|bottom
、center|start
)、角落(例如top|end
、bottom|start
)或CoordinatorLayout
的中心。这就是您使用FloatingActionButton
所做的事情:
<android.support.design.widget.FloatingActionButton
android:layout_gravity = "bottom|end"
[...]
>
您也可以使用例如工具栏来执行此操作。 Button
s 不能这样做,因为重力属性会影响按钮的内容,而不是它的位置。如果您想定位 Button
,请将其包裹在(例如)FrameLayout
或 Toolbar
中。确保环绕视图未设置为(显式或隐式)填充父级,例如使用FrameLayout
s,否则环绕视图将展开以填充整个框架,从而违背了设置其重力的目的。
<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 上工作