前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VV-安卓布局总汇篇

VV-安卓布局总汇篇

作者头像
张风捷特烈
发布2018-12-05 15:32:21
6600
发布2018-12-05 15:32:21
举报
零、前言

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

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

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

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

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

本文测试图标.png


一、首先说开发者选项中的两个布局分析利器:
1.布局的边框显示:
  • 模拟器的Dev Tools里,真机开发者选项里:

布局边界.png

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

过渡绘制.png

3.从一个布局看看用法:

布局的嵌套可能导致一篇区域被绘制多次,根据绘制的次数多少分为下面几种颜色: 原色 < 蓝色 < 绿色 < 粉色 < 红色 (吐槽:绿色 > 蓝色总觉得挺别扭)

待分析布局.png

layout/activity_over_draw.xml:用5个白色背景的RelativeLayout嵌套
代码语言:javascript
复制
<?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查看的特有属性 看起来挺多,但通过下面分分类,也就一目了然了

代码语言:javascript
复制
* @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

代码语言:javascript
复制
<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(子循父)
代码语言:javascript
复制
//与父控件左、上、右、下对齐
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.子控件主动找子控件(子循兄)
代码语言:javascript
复制
//参照属性
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中快速打入

代码语言:javascript
复制
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

代码语言:javascript
复制
<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
代码语言:javascript
复制
<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

代码语言:javascript
复制
<?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,但保留自己的位置信息,为布局提供参考

代码语言:javascript
复制
<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掉,有点鸡肋。

代码语言:javascript
复制
<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

代码语言:javascript
复制
<!--左-->
<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

代码语言:javascript
复制
<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----看到这里,我在此感谢你的喜欢与支持

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.11.02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 零、前言
    • 插播一段感悟:我经常思考工具与使用者间的关系:
      • 本文测试图标是svg的安卓xml版,通过精心挑选,如下:
      • 一、首先说开发者选项中的两个布局分析利器:
        • 1.布局的边框显示:
          • 2.布局的过渡绘制分析:
            • 3.从一个布局看看用法:
              • layout/activity_over_draw.xml:用5个白色背景的RelativeLayout嵌套
            • 4.讲一下布局的族谱:
            • 一、RelativeLayout
              • 1.gravity
                • 2.子控件主动找Parent(子循父)
                  • 3.子控件主动找子控件(子循兄)
                    • 4.通过一个图总结一下RelativeLayout
                    • 二、ConstraintLayout 约束布局
                      • 1.定位属性
                        • 2.边距属性
                          • 3.乖离率---bias:
                            • 4.比例宽高:layout_constraintDimensionRatio
                              • 5.控件链
                                • 6.三个不可视的辅助标签
                                  • 1).参考线辅助定位:Guideline
                                  • 2).组:Group
                                • 3).屏障:Barrier
                                • 后记:捷文规范
                                  • 1.本文成长记录及勘误表
                                    • 2.更多关于我
                                      • 3.声明
                                      领券
                                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档