4.4 FrameLayout与通用布局参数


4.4 FrameLayout 与通用布局参数

本节摘要:FrameLayout 把子控件统统摞在左上角,靠 layout_gravity 挪位,是叠放与占位场景的最简容器。本节讲它的两大本职——背景层叠与容器替代,再收束全章:margin 与 padding、gravity 与 layout_gravity 这两对通用属性,是所有容器共享的词汇。

最"懒"的容器反而不可替代

FrameLayout 的规则一句话讲完:子控件默认全部堆在左上角,后声明的盖在先声明的上面。听着简陋,但"叠放"这件事非它不可。猜数字 App 的两个场景都靠它:其一是表情图上叠状态角标——胜利时左上角浮一个金色星星:

<FrameLayout android:layout_width="96dp" android:layout_height="96dp"> <ImageView android:id="@+id/iv_face" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/ic_face_smile" /> <TextView android:id="@+id/tv_badge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top|end" android:text="WIN" android:textSize="10sp" /> </FrameLayout>

ImageView 铺满容器做底层,角标用 layout_gravity="top|end" 钉到右上角——gravity 值可以用竖线组合,一次钉住两根轴。其二是 Fragment 容器:Activity 布局里预留一个空的 FrameLayout 当"舞台",第 7 章的 DialogFragment、乃至更复杂的单 Activity 多页结构,都是往这个舞台里换演员。给它一个 id 就够了,它自己永远空着。

代码动态换演员也是三行的事:

supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, ResultFragment()) .commit()

⚠️ 注意:FrameLayout 不负责给子控件排队,用它装一列表单控件只会得到一摞叠罗汉。判断标准很简单——需要"排列"去找前三节,需要"叠放或占位"才来 FrameLayout。

margin 与 padding:一个往外一个往内

四套容器讲完,该把全章通用的词汇收进一个抽屉。第一对是 margin 与 padding,猜数字的按钮正好同时用到两者:

<Button android:id="@+id/btn_guess" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="16dp" android:padding="12dp" android:text="提交" />

margin控件边界之外的留白,向父容器申请;padding控件边界之内的留白,向自己的内容申请。按钮文字离边框远一点是 padding 的事,按钮离屏幕边缘远一点是 margin 的事。判断口诀:空白在框外是 margin,在框内是 padding。方向化版本 marginStart/endleft/right 更值得写——阿拉伯语等 RTL 布局下 start/end 会自动镜像,left/right 不会,这是 2.3 节可访问性话题在布局层的延伸。

gravity 与 layout_gravity:管内容与管自己

第二对易混属性本章出现过两次(1.1 的文字对齐、4.1 的标题居中),这里正式合并讲透:

<LinearLayout android:orientation="vertical" ...> <!-- layout_gravity:这个 TextView 自己在父容器里靠右 --> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" android:gravity="center" android:text="剩余次数 3" /> </LinearLayout>

前缀有无决定作用域:带 layout_ 前缀的是向父容器说话——"把我放在哪";不带的是向自己内部说话——"我的内容摆哪"。还有一个隐蔽陷阱:layout_gravity 的效果取决于父容器是谁——LinearLayout 竖排时 layout_gravity 管水平挪位(竖直方向被排队规则占用),FrameLayout 里则两轴都自由。同一行代码换个容器效果就变,这不是 bug,是"属性其实是发给父容器的请求"这一本质的体现。

图:两对通用属性的边界图解

图:两对通用属性的边界图解

本节要点回顾

  • FrameLayout 两大本职:叠放(底层图加浮层角标)与占位(Fragment 容器),别用它排列表单。
  • margin 框外、padding 框内:留白在谁的边界之外,就归谁管。
  • 优先 start/end 写法:RTL 语言下自动镜像,left/right 不会。
  • layout_gravity 是给父容器的请求:效果随容器种类变化,LinearLayout 竖排只管水平轴。
  • 四容器选型口诀:排队线性、贴邻相对、复杂约束、叠放占位 Frame——这一句就是第 4 章的压缩包。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U