之前写到了关于activity的显式启动和隐式启动,也就是关于Intent对象启动activity的不同方式,今天就来简单记录一下Android开发中关于layout的不同布局方式
layout就是布局,在前面也写到过关于Android项目结构中存放布局文件的layout文件夹,为了让组件(TextView,Button等)在不同的手机屏幕上都能运行良好(不同手机屏幕分辨率、尺寸并不完全相同),如果让程序手动控制每个组件的大小、位置,则将给编程带来巨大的困难,为了解决这个问题,Android提供了布局管理器。布局定义了应用中的界面结构(例如 Activity 的界面结构)。布局中的所有元素均使用 View 和 ViewGroup 对象的层次结构进行构建。View 通常用于绘制用户可看到并与之交互的内容。ViewGroup 则是不可见的容器,用于定义 View 和其他 ViewGroup 对象的布局结构,如图所示
每当Acitivity.setContentView(@LayoutRes int layoutResID)方法被调用,或者一个View通过LayoutInflater对象inflater出来,那么相关的布局文件就会被加载并解析出来。XML文件中每个大写的XML节点对应着一个View对象,他们被系统实例化。在Acitviity或者Fragment的整个生命周期中,他们都是UI层级的一部分。这会影响到应用程序使用过程中的分配
Android的布局管理器本身就是个UI组件,所有的布局管理器都是ViewGroup的子类,而ViewGroup是View的子类,所以布局管理器可以当成普通的UI组件使用,也可以作为容器类使用,可以调用多个重载addView()向布局管理器中添加组件,并且布局管理器可以互相嵌套,当然不推荐过多的嵌套(如果要兼容低端机型,最好不要超过5层)
LinearLayout又称作线性布局,是一种非常常用的布局。正如它的名字所描述的一样,这个布局会将它所包含的控件在线性方向上依次排列。既然是线性排列,肯定就不仅只有一个方向,这里一般只有两个方向:水平方向和垂直方向。主要以水平或垂直方式来排列界面中的控件。并将控件排列到一条直线上。在线性布局中,如果水平排列,垂直方向上只能放一个控件,如果垂直排列,水平方向上也只能方一个控件。
使用线性布局,需要将布局节点改成LinearLayout,基本格式如下:
....
用于控制线性布局的朝向
在线性布局中,控件排列有水平和垂直两个方向,控件排列方向由android:orientation属性来控制,该属性需要加在LinearLayout标记的属性中
用于设置线性布局内部的元素布局方式
线性布局的控件默认是从左往右排列或从上往下排列,如果想让线性布局中的控件排列对齐右边缘或者底部,可以用gravity属性控制
不过该属性值并不是只有在LinearLayout中才能使用,其他的布局用该属性同样能生效
TableLayout (表格布局)采用行、列的形式来管理控件,它不需要明确声明包含多少行、多少列,面是通过在TableLayout布局中添加TableRow布局或控件来控制表格的行数,可以在TableRow 布局中添加控件来控制表格的列数。在XML布局文件中定义表格布局的基本语法格式如下:
UI控件
</TableRow>
UI控件
</TableLayout>
TableLayout继承自LinearLayout, 因此它完全支持LinearLayout所支持的属性,此外,它还有其他的常用属性
用于设置指定的列为collapse(也就是隐藏)
设置可被隐藏的列,如:android:collapseColumns=~0”, 表示第1列可被隐藏
用于收缩宽度自适应父容器的大小
设置可被收缩的列,如:android:shrinkColumns=“1. 2”, 表示2, 3列可收编
用于拉伸,填充满表格
设置可被拉伸的列。如:android:stretchColumns-~0”, 表示第1列可被拉伸
相对布局(RelativeLayout)是一种根据父容器和兄弟控件作为参照来确定控件位置的布局方式。
核心属性
使用LinearLayout的时候也有一个问题,就是当界面比较复杂的时候,需要嵌套多层的 LinearLayout,这样就会降低UI Render的效率(渲染速度),而且如果是listview或者GridView上的 item,效率会更低,另外太多层LinearLayout嵌套会占用更多的系统资源,还有可能引发stackoverflow; 但是如果我们使用RelativeLayout的话,可能仅仅需要一层就可以完成了,以父容器或者兄弟组件参考+margin +padding就可以设置组件的显示位置,是比较方便的!当然,也不是绝对的,具体问题具体分析吧! 总结就是:尽量使用RelativeLayout + LinearLayout的weight属性搭配使用
绝对布局(Absolute Layout)就是指定元素的position属性为absloute,元素被指定为绝对定位后,浏览器会将其从流中删除
与浮动布局不同,浮动布局中浮动起来的元素,只是“半删除”。即对HTML端的块元素来说浮动起来的元素仿佛从流中被删除了。但对HTML端的内联元素来说浮动起来的元素仍旧存在
绝对布局就不是“半删除”了,而是从HTML流中彻底删除该元素。被删除的元素和原始HTML流中其他元素,处于不同层面,这就产生了分层的概念
绝对布局是前端布局中最为简单的布局,但灵活性极差,不具有自动适应设备分辨率的能力,就好比在手机上设置的布局,在平板上布局就会全部混乱,所以在日常开发中很少使用绝对布局
FrameLayout(帧布局)可以说是六大布局中最为简单的一个布局,这个布局直接在屏幕上开辟出一块空白的区域,当我们往里面添加控件的时候,会默认把他们放到这块区域的左上角,而这种布局方式却没有任何的定位方式,所以它应用的场景并不多;帧布局的大小由控件中最大的子控件决定,如果控件的大小一样大的话,那么同一时刻就只能看到最上面的那个组件!后续添加的控件会覆盖前一个!虽然默认会将控件放置在左上角,但是我们也可以通过layout_gravity属性,指定到其他的位置!
使用后面的画面覆盖前面的画面,从而实现动画的效果
FrameLayout的属性很少就两个,但是在说之前我们先介绍一个东西:
前景图像:永远处于帧布局最上面,直接面对用户的图像,就是不会被覆盖的图片。
两个属性:
设置改帧布局容器的前景图像
设置前景图像显示的位置
ConstraintLayout 是一个 ViewGroup,它的出现是为了解决复杂布局时,布局嵌套(布局内的布局)过多的问题(嵌套布局会增加绘制界面所需的时间)。它可以根据同级视图和父布局的约束条件为每个视图定义位置,类似于 RelativeLayout 所有视图都是根据兄弟视图和父级布局之间的关系来布局的,但是与 RelativeLayout 相比,它更加灵活,更易于使用。
在 Android 2.2 的版本中,为了给 ConstraintLayout 提供支持,Android 设计了新的布局编辑器。我们可以直接在布局编辑器当中拖动控件、添加约束,一气呵成。当然,在布局编辑器当中所做的操作,XML 布局当中就会自动生成对应的属性。
其中生成的一些属性,有可能并不是必须需要的。所以在生成后,你可能还需要手动检查、清理一下。或者你也可以直接在 XML 中编写属性,ConstraintLayout 的属性虽多,但是都是成组的,还是很容易掌握的。
在开发过程中经常能遇到一些复杂的UI,可能会出现布局嵌套过多的问题,嵌套得越多,设备绘制视图所需的时间和计算功耗也就越多。简单举个例子:
假设现在要写一个这样的布局,可能有人会这么写:
首先是一个垂直的LinearLayout,里面放两个水平的LinearLayout,然后在水平的LinearLayout里面放TextView。这样的写法就嵌套了两层LinearLayout。
有些人考虑到了嵌套布局带来的风险,所以用一个RelativeLayout来装下所有的控件。那么问题来了,既然用RelativeLayout可以解决问题,为什么还要使用ConstraintLayout呢?因为ConstraintLayout使用起来比RelativeLayout更灵活,性能更出色!还有一点就是ConstraintLayout可以按照比例约束控件位置和尺寸,能够更好地适配屏幕大小不同的机型
下面来看看相对定位的常用属性:
layout_constraintLeft_toLeftOf
layout_constraintLeft_toRightOf
layout_constraintRight_toLeftOf
layout_constraintRight_toRightOf
layout_constraintTop_toTopOf
layout_constraintTop_toBottomOf
layout_constraintBottom_toTopOf
layout_constraintBottom_toBottomOf
layout_constraintBaseline_toBaselineOf
layout_constraintStart_toEndOf
layout_constraintStart_toStartOf
layout_constraintEnd_toStartOf
layout_constraintEnd_toEndOf
以上就是关于layout的六大布局的一些记录,当然,只是一些简单的记录,并没有对其内容进行深挖和研究,在此就先按下不表,后面有机会可以进行一下研究