VV-安卓布局总汇篇
零、前言
一直以来觉得布局也没什么好讲的,特别是自从有了ConstraintLayout,拖拖接接基本上就行了
最近写个播放器,感觉布局并不是我想的这样简单,有的时候拖不出想要的结果,布局代码改不好也挺尴尬
脱出来的控件毕竟是IDE的智商,一个控件属性非常多,可读性不怎样,所以在此总结一下安卓的布局
插播一段感悟:我经常思考工具与使用者间的关系:
用工具
和会用工具
之差异:良庖岁更刀,割也;族庖月更刀,折也
,工具的使用方法体现了一位工匠
的技艺
《庖丁解牛》是我最喜欢的一篇古文,如何在做任何事上以无厚入有间,恢恢乎其于游刃必有余地矣
是我的思考
文中的八字成为我接触新事物的律典:依乎天理,因其固然
。通其理,方用之,是匠者
与匠师
的差异
如果你不懂牛的构造原理,拿一把屠刀固然可杀牛取肉,但庖丁:以神遇而不以目视,官知止而神欲行
提刀而立,为之四顾,为之踌躇满志,善刀而藏之
的感觉也就与你无缘,而这是一位匠者的自豪。
写一个程序就像打造一件艺术品,制造的过程便是
解牛
,IDE、API、运行环境就是我手中的剑
普通屠夫遇牛则斩,好肉坏肉在一起切,煮成一大杂烩。庖丁的匠心独运是我追求的境界:
吾生也有涯,而知也无涯,以有涯随无涯
愿君且行且珍惜。
本文测试图标是svg的安卓xml版,通过精心挑选,如下:
本文测试图标.png一、首先说开发者选项中的两个布局分析利器:
1.布局的边框显示:
- 模拟器的Dev Tools里,真机开发者选项里:
2.布局的过渡绘制分析:
- 也在开发者选项里,不过不是切换按钮,里面有选项,一般选第二个,如果绿色色弱选第三个(还挺贴心)
3.从一个布局看看用法:
待分析布局.png布局的嵌套可能导致一篇区域被绘制多次,根据绘制的次数多少分为下面几种颜色:
原色 < 蓝色 < 绿色 < 粉色 < 红色
(吐槽:绿色 > 蓝色总觉得挺别扭)
layout/activity_over_draw.xml:用5个白色背景的RelativeLayout嵌套
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="350dp"
android:layout_height="350dp"
android:background="@android:color/white"
android:gravity="center"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerInParent="true"
android:background="@android:color/white">
<RelativeLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:background="@android:color/white">
<RelativeLayout
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:background="@android:color/white">
<RelativeLayout
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:background="@android:color/white">
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
4.讲一下布局的族谱:
常见布局.png可见XXXLayout都继承自ViewGroup,最终都是View,所以View、ViewGroup的通用布局属性都可以用
不同的布局有自己独特的布局属性、详见后文
一、RelativeLayout
从RelativeLayout源码总寻找@attr查看的特有属性
看起来挺多,但通过下面分分类,也就一目了然了
* @attr RelativeLayout_ gravity
* @attr RelativeLayout_ ignoreGravity
* @attr RelativeLayout_Layout_ layout_alignWithParentIfMissing
* @attr RelativeLayout_Layout_ layout_toLeftOf
* @attr RelativeLayout_Layout_ layout_toRightOf
* @attr RelativeLayout_Layout_ layout_above
* @attr RelativeLayout_Layout_ layout_below
* @attr RelativeLayout_Layout_ layout_alignBaseline
* @attr RelativeLayout_Layout_ layout_alignLeft
* @attr RelativeLayout_Layout_ layout_alignTop
* @attr RelativeLayout_Layout_ layout_alignRight
* @attr RelativeLayout_Layout_ layout_alignBottom
* @attr RelativeLayout_Layout_ layout_alignParentLeft
* @attr RelativeLayout_Layout_ layout_alignParentTop
* @attr RelativeLayout_Layout_ layout_alignParentRight
* @attr RelativeLayout_Layout_ layout_alignParentBottom
* @attr RelativeLayout_Layout_ layout_centerInParent
* @attr RelativeLayout_Layout_ layout_centerHorizontal
* @attr RelativeLayout_Layout_ layout_centerVertical
* @attr RelativeLayout_Layout_ layout_toStartOf
* @attr RelativeLayout_Layout_ layout_toEndOf
* @attr RelativeLayout_Layout_ layout_alignStart
* @attr RelativeLayout_Layout_ layout_alignEnd
* @attr RelativeLayout_Layout_ layout_alignParentStart
* @attr RelativeLayout_Layout_ layout_alignParentEnd
1.gravity
gravity.png决定内部控件摆放的位置(父控件主动)
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="250dp"
android:layout_height="250dp"
android:background="@android:color/white"
android:gravity="center_horizontal"
tools:context=".MainActivity">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/icon_center"/>
</RelativeLayout>
2.子控件主动找Parent(子循父)
//与父控件左、上、右、下对齐
layout_alignParentLeft 、layout_alignParentTop 、layout_alignParentRight 、layout_alignParentBottom
//居中、水平居中、垂直居中
layout_centerInParent 、layout_centerHorizontal 、layout_centerVertical
//效果等同于-layout_alignParentLeft、layout_alignParentRight,AndroidStudio推荐使用这两个
layout_alignParentStart 、layout_alignParentEnd
RelativeLayout子循父属性一览.png
3.子控件主动找子控件(子循兄)
//参照属性
layout_above、layout_below
layout_toLeftOf、layout_toRightOf == layout_toStartOf、layout_toEndOf
//对齐属性
layout_alignTop、layout_alignBottom、layout_alignBaseline
layout_alignLeft、layout_alignRight == layout_alignStart、layout_alignEnd
RelativeLayout子循兄属性一览.png
4.通过一个图总结一下RelativeLayout
边距.png布局文件见文后源码,有点长,不贴了
这里说一下:padding和margin,两者都可以让自己与旁边的控件产生间隙,区别在于:
比如你在一个大箱子里,又被箱子里的石头紧紧困住,padding就像缩小自己寻求空隙,margin就是把石头推开
当margin太大,石头不能往外偏移了,石头就会如图四
二、ConstraintLayout 约束布局
大学时学solidworks(3D软件)时便对约束有很深的印象,约束可以实现复杂结构的关联
1.定位属性
AndroidStudio中快速打入
ste == layout_constraintStart_toEndOf
ss == layout_constraintStart_toStartOf
es == layout_constraintEnd_toStartOf
ete == layout_constraintEnd_toEndOf
ttt == layout_constraintTop_toTopOf
ttb == layout_constraintTop_toBottomOf
btt == layout_constraintBottom_toTopOf
btb == layout_constraintBottom_toBottomOf
ConstraintLayout定位属性一览.png
ConstraintLayout样例.png
2.边距属性
待定位边距属性一览.png3.乖离率---bias:
layout_constraintHorizontal_bias
layout_constraintVertical_bias
Horizontal_bias.png头接父头,尾接父尾,长宽固定的情况不能实现:
实验一下,结果居中了,调节layout_constraintHorizontal_bias
的值(0~1)
<ImageView
android:id="@+id/id_iv_center"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/icon_center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias=".9"
app:layout_constraintStart_toStartOf="parent"/>
4.比例宽高:layout_constraintDimensionRatio
<ImageView
android:id="@+id/id_iv_center"
android:layout_width="50dp"
android:layout_height="0dp"
android:src="@drawable/icon_center"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="1:4"
android:background="@color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
比例宽高.png
5.控件链
还记得是结构的双链表吧,除首位节点,其他都持有前后的引用,这里约束也相似
也能实现一个接着一个,后面有连到前面的结构。
链.png链模式:加在链头,加在链头,加在链头(重要的话说三遍)
水平链模式:layout_constraintHorizontal_chainStyle
垂直链模式:layout_constraintVertical_chainStyle
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="230dp"
android:layout_height="230dp"
android:background="@android:color/white">
<!--左-->
<ImageView
android:id="@+id/id_iv_left"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/icon_left"
app:layout_constraintHorizontal_bias=".3"
app:layout_constraintEnd_toStartOf="@id/id_iv_right"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteY="0dp"/>
<!--右-->
<ImageView
android:id="@+id/id_iv_right"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/icon_right"
app:layout_constraintEnd_toStartOf="@+id/id_iv_top"
app:layout_constraintStart_toEndOf="@id/id_iv_left"/>
<!--上-->
<ImageView
android:id="@+id/id_iv_top"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/icon_top"
app:layout_constraintEnd_toStartOf="@id/id_iv_bottom"
app:layout_constraintStart_toEndOf="@id/id_iv_right"/>
<!--下-->
<ImageView
android:id="@+id/id_iv_bottom"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/icon_bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/id_iv_top"/>
</android.support.constraint.ConstraintLayout>
注:链自己写比较麻烦,可以在预览区选中,自动生成:
自动生成链.png6.三个不可视的辅助标签
1).参考线辅助定位:Guideline
就当是一个gone的view,但保留自己的位置信息,为布局提供参考
<android.support.constraint.Guideline
android:id="@+id/center_in_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"/>
Guideline.png
2).组:Group
试了一下,并不像我想象中的那么强大,不能靠分组定位。可在代码里同组Gone掉,有点鸡肋。
<android.support.constraint.Group
android:id="@+id/id_left_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:constraint_referenced_ids="id_iv_left,id_iv_right"/>
3).屏障:Barrier
barrier.png这个挺不错的,将view打包,提供一个约束参考,有点像分组定位,可惜貌似只能一边。可看作一个透明的墙,能提供依靠。
<!--左-->
<ImageView
android:id="@+id/id_iv_left"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/icon_left"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<!--右-->
<ImageView
android:id="@+id/id_iv_right"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/icon_right"
app:layout_constraintStart_toEndOf="@id/id_iv_left"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/id_iv_center"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/icon_center"
app:layout_constraintTop_toBottomOf="@id/barrier"/>
<android.support.constraint.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="id_iv_left,id_iv_right"
app:barrierDirection="bottom"/>
三、最后举一个小栗子
比较.png可以看出ConstraintLayout可以减少布局的层次,减少过渡绘制的次数
一个0.65的竖直参考线,三个图标形成链,顶底对齐父控件
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginTop="100dp"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="horizontal">
<ImageView
android:id="@+id/id_iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@mipmap/icon_default"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/id_tv_music_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="勇气"
android:textColor="#363636"
android:textSize="18dp"
app:layout_constraintBottom_toTopOf="@id/id_tv_singer"
app:layout_constraintStart_toEndOf="@id/id_iv_icon"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/id_tv_singer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="葛强丽"
android:textColor="#898989"
android:textSize="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@id/id_tv_music_name"
app:layout_constraintTop_toBottomOf="@id/id_tv_music_name"/>
<ImageView
android:id="@+id/id_iv_ctrl"
android:layout_width="28sp"
android:layout_height="28sp"
android:layout_toStartOf="@id/id_iv_next"
android:src="@drawable/icon_stop_2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/id_iv_next"
app:layout_constraintStart_toStartOf="@+id/point7_h"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/id_iv_next"
android:layout_width="28sp"
android:layout_height="28sp"
android:layout_toStartOf="@id/id_iv_pre_list"
android:src="@drawable/icon_next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/id_iv_pre_list"
app:layout_constraintStart_toEndOf="@+id/id_iv_ctrl"
app:layout_constraintTop_toTopOf="parent"/>
<android.support.constraint.Guideline
android:id="@+id/point7_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.65"/>
<ImageView
android:id="@+id/id_iv_pre_list"
android:layout_width="28sp"
android:layout_height="28sp"
android:src="@drawable/icon_music_list"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/id_iv_next"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
后记:捷文规范
1.本文成长记录及勘误表
项目源码 | 日期 | 备注 |
---|---|---|
V0.1--无 | 2018-11-2 | VV-安卓布局总汇篇 |
2.更多关于我
笔名 | 微信 | 爱好 | |
---|---|---|---|
张风捷特烈 | 1981462002 | zdl1994328 | 语言 |
我的github | 我的简书 | 我的CSDN | 个人网站 |
3.声明
1----本文由张风捷特烈原创,转载请注明
2----欢迎广大编程爱好者共同交流
3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正
4----看到这里,我在此感谢你的喜欢与支持