FrameLayout系列:FrameLayout三连问

Posted zhangjin1120

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FrameLayout系列:FrameLayout三连问相关的知识,希望对你有一定的参考价值。

布局专栏里面一直缺一篇FrameLayout的文章。

目录

FrameLayout在哪里用到了?

1. DecorView

DecorView的完整路径,是com.android.internal.policy.DecorView。Android studio中双击shift搜索,能找到DecorView的源代码,如下图:

从源码可以看到,DecorView extends FrameLayout:

Activity中,View树的根布局就是DecorView。如下图,DecorView内部分了三次,最底层是一个LinearLayout,它上面覆盖了一个id为navigationBarBackground的View,就是底部导航栏。最上面是一个id为statusBarBackground的View,也就是顶部状态栏。这是明显的分层布局,所以用了FrameLayout。

2. 动态加载Fragmemt

具体代码见:Fragment系列:使用FrameLayout动态加载

3. Activity.java的源码中,setContentView()的父布局

从上图中,我们可以看大一个id为content的FragmentLayout,他内部的RelativeLayout是我自己写的activity_main.xml文件的根布局。 切换到Project模式——>找到External Libraries——>对应的编译API,例如Android API 32 Platform ——>res ——>layout文件夹下——>找到R.layout.screen_simple

打开再核对下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">
    <ViewStub android:id="@+id/action_mode_bar_stub"
              android:inflatedId="@+id/action_mode_bar"
              android:layout="@layout/action_mode_bar"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:theme="?attr/actionBarTheme" />
    <FrameLayout
         android:id="@android:id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:foregroundInsidePadding="false"
         android:foregroundGravity="fill_horizontal|top"
         android:foreground="?android:attr/windowContentOverlay" />
</LinearLayout>

这里使用FrameLayout的原因和加载Fragment是一致的,因为Activity和Fragment传递过来的都是单个布局。FrameLayout只充当一个容器。

官网对于FrameLayout的定位是什么?

https://developer.android.google.cn/reference/android/widget/FrameLayout

英文原文还是更好理解一些:

FrameLayout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that’s scalable to different screen sizes without the children overlapping each other.

You can, however, add multiple children to a FrameLayout and control their position within the FrameLayout by assigning gravity to each child, using the android:layout_gravity attribute.

Child views are drawn in a stack, with the most recently added child on top. The size of the FrameLayout is the size of its largest child (plus padding), visible or not (if the FrameLayout’s parent permits). Views that are View.GONE are used for sizing only if setConsiderGoneChildrenWhenMeasuring() is set to true.

这段介绍强调了single,也就是说FrameLayout的设计初衷是只显示单个item。
第二段话,讲到了,但是FrameLayout还是可以添加多个子view,然后用layout_gravity来控制位置。第三段话不太重要,不纠结。

什么时候使用FrameLayout?

  1. 单个布局的父容器。例如自定义Activity根布局的父容器,单个Fragment也添加到FrameLayout里面。
  2. 明显分层的多个子View。例如:系统自带的DecorView。还有《疯狂Android讲义》这本书里面用FrameLayout实现的霓虹灯效果,如下图:

    源码可以参考:https://blog.csdn.net/peotry_favour/article/details/88660457

FrameLayout讲到这个深度,对于平时使用,已经足够了。

推荐阅读:
Android-DecorView-一窥全貌(下)
Android-DecorView-一窥全貌(上)

以上是关于FrameLayout系列:FrameLayout三连问的主要内容,如果未能解决你的问题,请参考以下文章

带圆角的 FrameLayout

重力设置动态不适用于 Framelayout

FrameLayout to RelativeLayout ClassCastException 即使没有使用 FrameLayout

在 FrameLayout 中显示 TextView

FrameLayout 中的 MergeRootFrame 是啥?

FrameLayout帧布局