Android基础 - 如何做鲁棒性更高的布局

code小生,一个专注 Android 领域的技术平台

公众号回复 Android 加入我的安卓技术群

作者:kongzue
链接:https://www.jianshu.com/p/174bcb6c0d93
声明:本文已获
kongzue授权发表,转发等请联系原作者授权

前情提要

这是一篇写给入坑 Android 开发新手的文章,它可能不太适合老手阅读,也可能带有一些我个人的理解和见地,但我是衷心希望更多的新人开发者能从这篇文章中获取知识,让我们一同进步。当然了,其中可能不可避免的会存在一些遗漏和错误,也希望大家多多指正。

目录

· 什么是布局&盒子模型
· 尽可能使用LinearLayout构建布局
· 颅内秒建模,指哪打哪
· 还有被遗忘的图片兄弟咋办呀?

什么是布局&盒子模型

移动智能设备是目前最火的人机交互设备之一,应市场的召唤,作为开发者的我们想要在这样的设备中开发出优质的作品那么就需要让我们的产品具备更好的视觉和功能体验,而布局,正是构建视觉体验的基础。良好的布局构建可以帮助我们更快、更好的完成一个应用视觉开发,那么将UI产出的图形稿件变现成为可以操作的APP界面,我们就应该能够完成鲁棒性更高的布局开发。

布局开发是APP前端开发中最重要的一环,而目前我们所做的大部分APP开发离不开一种模型,即盒子模型,字面意思理解,就是一个盒子套一个盒子,外边的盒子位置的变动里边的小盒子也会跟着变,反映到布局上,即父布局和子布局,但是注意了,在Android提供的基础组件中,有些组件可以构成所谓的“盒子”,而有些组件则不行,他们只能作为放在盒子内部拿来使用的存在。典型的“盒子”即继承自父类“ViewGroup”的相对布局 RelativeLayout 以及线性布局 LinearLayout,当然了还有滚动布局 ScrollView、网格布局 GridLayout 等十分的多,而我们日常使用到的按钮 Button、图像ImageView、文本TextView则不是“盒子”了,他们只能作为子布局放在盒子内,以上,就是盒子模型的简单陈述了。

尽可能使用LinearLayout构建布局

相对布局RelativeLayout可能是新手入坑Android开发后最常用的布局,因为其跟我们日常所理解的画布类似,我们想将哪个部件放在画布的哪个位置都是非常自由的,但事实上,从结构的完整性上讲,RelativeLayout并不是真正适合作为布局主体进行布局构建方式,虽然看似其十分好用,但实际上当我们将作为底子的画布变换一个方向和大小,可能就没那么方便了:

640?wx_fmt=other
使用RelativeLayout构建的布局.png

这可能会直接导致界面混乱,以至于出现“换了个手机就不能用了”的尴尬情况,那么如何避免此类问题呢?事实上,可能让我们觉得并不好用的LinearLayout就可以帮我们更好的解决这个问题。

640?wx_fmt=other
使用LinearLayout构建的布局没有问题.png

使用LinearLayout布局可以更加方便的完成如上图所示的布局,但在此之前,我们需要明白一个在LinearLayout布局中的子布局特有的属性:layout_weight,当一个子布局放在LinearLayout中的时候,layout_weight属性即可使用,它的意义在于“权重”,在线性布局中,子布局都是按照从上到下、从左到右来排列的,但当子布局的宽度或高度为match_parent,即占满父布局的全部宽高度时,这里就会存在一个问题,其他的子布局会被挤出屏幕外,此时要让他们“平均”显示,就需要一个参数layout_weight了,将所有子布局设置layout_weight="1",你就会发现他们在父布局中被等分宽高了,利用这个特性原理来构建布局则可以轻松做到健壮性更高不具效果而不需要担心很多界面重叠、错位的问题:

640?wx_fmt=other
相对布局和线性布局.png

我个人相对更推荐线性布局为主进行主体布局的开发,这样可以规避掉很多问题,提升布局的鲁棒性。具体表现在哪里呢?看下边这个截图:

640?wx_fmt=other
要实现的效果.png

我们要实现上边的这个效果,用相对布局的代码如下:

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">


        <Button
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:text="1" />


        <Button
            android:id="@+id/button2"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:text="2" />


        <Button
            android:id="@+id/button3"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_below="@+id/button2"
            android:layout_toLeftOf="@+id/button2"
            android:layout_toStartOf="@+id/button2"
            android:text="3" />


    </RelativeLayout>

用线性布局写的代码如下:

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">


            <Button
                android:id="@+id/button1"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:text="1" />


            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_weight="1" />


            <Button
                android:id="@+id/button2"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:text="2" />


        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">


            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_weight="1" />


            <Button
                android:id="@+id/button3"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:text="3" />


            <View
                android:layout_width="70dp"
                android:layout_height="70dp" />


        </LinearLayout>
    </LinearLayout>

看似线性布局的代码多了是不是?那么它的优势到底在哪里呢?所谓鲁棒性,可以理解成可靠性,也于容错性相关,那么你在下边的线性布局方案中可有见过一句android:layout_toLeftOf、android:layout_toStartOf之类的需要绑定其他组件的语句么?这里最关键的意义在于,采用线性布局构建的代码方案中,不存在某个子布局组件和其他子布局组件存在关联关系的情况,那么这在后期维护项目的过程中,如果出现需要删除、隐藏掉其可能存在关联关系的布局的情况时,我们的界面不会出现任何错误的情况,其鲁棒性远高于采用相对布局的代码。

如果经历过大型项目我们都会知道,在大型项目中可能存在大量的布局、组件,这样的情况下如果需要对其中某一部分进行修改,那么极可能出现牵一发而动全身的问题,很多问题还不会立刻表现出来,而是会在某些条件达成时出现问题,带来不良的用户体验,因此,在日常布局设计时,除了可能存在需要居中某些子布局组件而使用相对布局的情况外,我建议能使用线性布局就是用线性布局来进行构建。

颅内秒建模,指哪打哪

相对一些特殊的应用,我们日常能遇到需要开发的大多是一些业务系统,而这,更是线性布局的主场了。

640?wx_fmt=other
一日读.png

「一日读」是我开源在Github上的轻图片、视频以及知乎日报功能的客户端( https://github.com/kongzue/EnjoyLife ),这里就拿它的关于界面来举例好了,在这个界面中,主体采用了一个顶屏幕宽高的纵向LinearLayout,里边的图片、文字都是采用margin的形式进行分隔,而顶部的导航条,则需要悬浮在主界面之上,那么它则采用了一个横向的线性布局作为主体设计了返回按钮、分享按钮以及标题,但其中的标题需要居中,则在其上叠加了一层相对布局来完成。

此布局在横向、各种分辨率(非极端)的情况下均不会出现任何问题,且因为不存在大量的相对代码,维护成本更低。

彩蛋·还有被遗忘的图片兄弟咋办呀?

线性布局相对于相对布局确实更具优势,但在我们开发过程中也会遇到有一些采用更高分辨率、更奇葩的比例、或非常见的更高dpi的手机,此时就可能存在一个问题了,我们可爱好看的背景图被无情的拉伸了,那么这种问题如何解决呢?

以软件开屏的闪屏图为例,在16:9的手机上和19:9的手机上可能出现如下效果:

640?wx_fmt=other
闪屏图.png

显然,我们一般的开发都是基于16:9的设备进行的,而在全面屏大行其道的今天,出现18:9,甚至19:9的手机也不足为奇,而这种情况下,我们闪屏页的布局中广告图部分的高度就发生了变化,正常方式下要么出现上下白边,要么出现被拉伸,那么这里就要用到ImageView的属性:

android:scaleType="centerInside"

使用此属性的ImageView会以内等比例顶宽高缩放,以保证图像能够占满布局,而这里也需要UI小姐姐们在出图时尽可能避免内容贴边的情况,这样的适配就不会出现问题了。

尾巴

根据适合的业务逻辑采用适合的布局架构可以轻松节省维护成本和构建时间,对于软件的健壮性上都会有不错的提升,重复性劳动是我们在开发过程中最需要避免的,而良好的布局基础则是软件能够运营维护得更长远的根本,此篇文章主要分享的是我在开发设计布局中的一些见解,如果不对还希望大家多多指正,也希望大家养成良好的布局习惯,做出更好用的软件。

性能相关

Android 性能小技巧

640

分享技术我是认真的

猜你喜欢

转载自blog.csdn.net/H176Nhx7/article/details/82847954