VV-安卓布局总汇篇

零、前言

一直以来觉得布局也没什么好讲的,特别是自从有了ConstraintLayout,拖拖接接基本上就行了 最近写个播放器,感觉布局并不是我想的这样简单,有的时候拖不出想要的结果,布局代码改不好也挺尴尬 脱出来的控件毕竟是IDE的智商,一个控件属性非常多,可读性不怎样,所以在此总结一下安卓的布局

插播一段感悟:我经常思考工具与使用者间的关系:

用工具会用工具之差异:良庖岁更刀,割也;族庖月更刀,折也,工具的使用方法体现了一位工匠的技艺 《庖丁解牛》是我最喜欢的一篇古文,如何在做任何事上以无厚入有间,恢恢乎其于游刃必有余地矣是我的思考 文中的八字成为我接触新事物的律典:依乎天理,因其固然。通其理,方用之,是匠者匠师的差异 如果你不懂牛的构造原理,拿一把屠刀固然可杀牛取肉,但庖丁:以神遇而不以目视,官知止而神欲行 提刀而立,为之四顾,为之踌躇满志,善刀而藏之的感觉也就与你无缘,而这是一位匠者的自豪。

写一个程序就像打造一件艺术品,制造的过程便是解牛,IDE、API、运行环境就是我手中的剑 普通屠夫遇牛则斩,好肉坏肉在一起切,煮成一大杂烩。庖丁的匠心独运是我追求的境界: 吾生也有涯,而知也无涯,以有涯随无涯 愿君且行且珍惜。

本文测试图标是svg的安卓xml版,通过精心挑选,如下:

本文测试图标.png


一、首先说开发者选项中的两个布局分析利器:

1.布局的边框显示:
  • 模拟器的Dev Tools里,真机开发者选项里:

布局边界.png

2.布局的过渡绘制分析:
  • 也在开发者选项里,不过不是切换按钮,里面有选项,一般选第二个,如果绿色色弱选第三个(还挺贴心)

过渡绘制.png

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.讲一下布局的族谱:

可见XXXLayout都继承自ViewGroup,最终都是View,所以View、ViewGroup的通用布局属性都可以用 不同的布局有自己独特的布局属性、详见后文

常见布局.png

一、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

布局文件见文后源码,有点长,不贴了 这里说一下:padding和margin,两者都可以让自己与旁边的控件产生间隙,区别在于: 比如你在一个大箱子里,又被箱子里的石头紧紧困住,padding就像缩小自己寻求空隙,margin就是把石头推开 当margin太大,石头不能往外偏移了,石头就会如图四

边距.png


二、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.边距属性

待定位边距属性一览.png


3.乖离率---bias:

layout_constraintHorizontal_bias layout_constraintVertical_bias

头接父头,尾接父尾,长宽固定的情况不能实现: 实验一下,结果居中了,调节layout_constraintHorizontal_bias的值(0~1)

Horizontal_bias.png

<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.控件链

还记得是结构的双链表吧,除首位节点,其他都持有前后的引用,这里约束也相似 也能实现一个接着一个,后面有连到前面的结构。

链模式:加在链头,加在链头,加在链头(重要的话说三遍) 水平链模式:layout_constraintHorizontal_chainStyle 垂直链模式:layout_constraintVertical_chainStyle

链.png

<?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>

注:链自己写比较麻烦,可以在预览区选中,自动生成:

自动生成链.png


6.三个不可视的辅助标签
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

这个挺不错的,将view打包,提供一个约束参考,有点像分组定位,可惜貌似只能一边。可看作一个透明的墙,能提供依靠。

barrier.png

<!--左-->
<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"/>

三、最后举一个小栗子

可以看出ConstraintLayout可以减少布局的层次,减少过渡绘制的次数 一个0.65的竖直参考线,三个图标形成链,顶底对齐父控件

比较.png

<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.更多关于我

笔名

QQ

微信

爱好

张风捷特烈

1981462002

zdl1994328

语言

我的github

我的简书

我的CSDN

个人网站

3.声明

1----本文由张风捷特烈原创,转载请注明 2----欢迎广大编程爱好者共同交流 3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正 4----看到这里,我在此感谢你的喜欢与支持

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏james大数据架构

Android中关于dip和px以及转换的总结

我们在页面布局的时候,经常会设置容器的长度,但是到底该使用哪个作为长度的单位而懊恼。在Android中支持的描述大小区域的类型有以下几种: px(pixels)...

19850
来自专栏程序员互动联盟

【专业技术】搜狗歌词窗口如何来实现

大家都见过以前Sogou歌词窗口的样子吧,感觉是歌词的字体直接贴在windows桌面上一样,但是还可以用鼠标控制,这个是怎么做成的呢?其实我也不知道^_^,估计...

384100
来自专栏水击三千

ArcGIS for Android学习(一)

GIS的开发中,什么时候都少不了地图操作。ArcGIS for Android中,地图组件就是MapView,MapView是基于Android中ViewGro...

1.6K60
来自专栏HTML5学堂

几个前端工程师应当掌握的“词语”

HTML5学堂-码匠:W3C、BFC、FOUC、Hack、GPU、Sprite、UA……各类前端术语知多少? 有不少前端开发工程师,可能并不清楚下面的部分词语,...

36960
来自专栏守候书阁

编写自己的代码库(css3常用动画的实现)

在月初的时候,发了CSS3热身实战--过渡与动画(实现炫酷下拉,手风琴,无缝滚动)。js的代码库也发过两次,两篇文章。之前也写了css3的热身实战,既然热身完了...

21220
来自专栏非著名程序员

基础篇章:React Native之 ScrollView 的讲解

(友情提示:RN学习,从最基础的开始,大家不要嫌弃太基础,会的同学请自行略过,希望不要耽误已经会的同学的宝贵时间) 编者按:其实我并不太喜欢在周末发公众号,毕竟...

29350
来自专栏编程之旅

iOS开发——影响图形性能的因素以及检测方法

我想各位攻城狮们肯定听过一句话:“过早的优化是万恶之源”。若是你有着丰富的项目经验,一定会对这句话有着自己的体会,而若是编程新手,那么,请牢记这句话。在一个项目...

13520
来自专栏葬爱家族

Android高级动画(4)完结篇目录回顾封装库总结

Android高级动画(1)http://www.jianshu.com/p/48554844a2db Android高级动画(2)http://www.ji...

20120
来自专栏移动端开发

iOS 动画笔记 (一)

你也肯定喜欢炫酷的动画! 在APP中,动画就是一个点睛之笔!可以给用户增加一些独特的体验感,估计也有许多的和我一样的,看着那些觉得不错的动画,也就只能流口...

24880
来自专栏Android先生

细细品读!深入浅出,官方文档看ConstraintLayout

ConstraintLayout和其他布局一样,继承自ViewGroup,但是不同点在于它调整控件的位置和大小时更加得灵活,功能更加强大。

8940

扫码关注云+社区

领取腾讯云代金券