07. 【Android教程】Android 线性布局 LinearLayout

在上一节中,我们讲到了所有的 Layout 都是从 ViewGroup 继承而来,它可以包含若干 View 并按照指定的规则将这个 View 摆放到屏幕上。那么接下来的章节我们就来学习一下 Android 的 UI 布局,Android 原生有六大布局,分别是: LinearLayout(线性布局)、RelativeLayout(相对布局)、TableLayout(表格布局)、FrameLayout(帧布局)、AbsoluteLayout(绝对布局)、GridLayout(网格布局),我们从最简单实用的一个布局开始:LinearLayout。

1. LinearLayout 的特性

LinearLayout 继承自 ViewGroup,可以将所包含的 View 按照线性方式一个一个的排列起来,即将 View 排列成一行(水平布局)或者排列成一列(垂直布局)。LinearLayout 有一个很关键的属性:android:orientation,可以用它来设置布局的方向,默认是横向。

2. 常用设置

在编写布局代码之前,我们先来了解一下 LinearLayout 常用的设置项。

2.1 基本属性:

  • id: 布局唯一 id,用来在代码中通过 findViewById 查找该布局,获取布局对象
  • layout_height: 设置布局高度,有三种可选值:
    • 具体高度(dp、px)
    • wrap_content: 布局高度由子 View 的高度而定
    • match_parent: 布局高度占满父布局(等同于 fill_parent,后者已被废弃,后文将直接使用 match_parent 替代 fill_parent)
  • layout_width: 设置布局宽度,同 layout_height
  • layout_gravity: 设置布局在其父布局中的对齐方式,有以下几种常用值:
    • top: 顶端对齐
    • bottom: 底部对齐
    • left: 居左对齐
    • right: 居右对齐
    • center: 居中对齐
      可以组合使用,比如left|top表示左上对齐
  • gravity: 设置布局内的各个 View / Viewgroup 的对齐方式,使用方法同 layout_gravity
  • background: 设置布局的背景样式,可以用图片或者颜色作为背景
  • layout_margin: 设置元素与周围其他元素的间距,类似的还可以设置单边的间距:
    • layout_marginRight
    • layout_marginTop
    • layout_marginLeft
    • layout_marginBottom

以上是大多数布局都会有的属性,在这一节讲的相对详细,后续出现可参考本节内容

2.2 特殊属性

  • orientation: 线性布局的方向,前面提到过可以用它决定内部 View 的排列方向。
  • layout_weight: 内部 View 的大小权重,这个是 LinearLayout 里很重要的一个设置,它将 LinearLayout 内部的 View 按照一定比例分配大小,具体使用后面会详细介绍
  • divider: 设置布局之间的分割线,可以通过图片指定样式
  • dividerPadding: 分割线之间的间距
  • showDividers: 设置分割线的位置,有以下可选值:
    • beginning: 在元素之前展示分割线
    • end: 在元素之后展示分割线
    • middle: 在每个元素之间展示分割线
    • none: 不展示

3. 编写垂直样式布局

线性布局分为垂直和水平布局两种方式,在使用过程中除了方向不同,其余类似。本节仅演示垂直样式,水平样式相信你能够触类旁通。
顾名思义,垂直布局就是将内部 View 从上到下依次排成一列,为了便于理解,直接上代码,在我们新建的工程中,找到“res->layout->activity_main.xml”,编写代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:text="Here"android:background="#E71B0C"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:text="Is"android:background="#E7430F"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:text="mybj123"android:background="#E6D11B"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:background="#88F10D"android:text="Android"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:background="#03A9F4"android:text="Study"/></LinearLayout>

在屏幕中有 5 个 TextView 按照垂直方向依次排成一列。注意,Layout 都是继承自 ViewGroup 的,在上一节我们说过 ViewGroup 也是 View,所以我们可以推理出 Layout 里面也是可以放 Layout 的。按照这个逻辑我们还可以在垂直布局中嵌套水平布局,比如我们希望把“Here Is”和“Android Study”这两个短语写到一排:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#E71B0C"android:text="Here"android:textSize="30sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#E7430F"android:text="Is"android:textSize="30sp" /></LinearLayout><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#E6D11B"android:text="mybj123"android:textSize="30sp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#88F10D"android:text="Android"android:textSize="30sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#03A9F4"android:text="Study"android:textSize="30sp" /></LinearLayout></LinearLayout>

我们将“Here”和“Is”、“Android”和“Study”这四个 TextView 两两一组分别放到了一个水平样式的 LinearLayout 中,这样验证了,Layout 是可以嵌套使用的。

4. weight 的使用

以上是 LinearLayout 排列方式的使用,接下来讲到一个很关键的属性——weight,它可以使内部 View 按照一定的比例配置尺寸,有同学可能会有疑问,前面不是有layout_heightlayout_width用来设置尺寸吗?那它和layout_weight有什么关系,会不会有什么冲突?带着这个疑问,一起学习 weight 的用法吧。

layout_weight是 LinearLayout 特有的一个属性,它很好的利用了线性布局的特点,让系统自适应的帮我们完成比例缩放。和你想的一样,它和layout_widthlayout_height密不可分,他们的相互影响,最终的尺寸有很多种计算方法。这里提供一种我认为最简单的理解:

先按照 layout_height / layout_width 的设置分配所需大小,然后剩下的空间按照 weight 的比例分配,最终加起来的尺寸就是各个 View 的最终尺寸。

关于 layout_height / layout_width 可以大致分为 3 种情况:

  • 高度 / 宽度设置为 0
  • 高度 / 宽度为 wrap_content
  • 高度 / 宽度为 match_parent
    以下就针对这三种情况详细说明。

4.1 设置成 0 dp(重点)

这个是最直接,最常用的设置方式,也是我们需要掌握的重中之重。如果我们将高度设置成 0 dp,那么系统就会直接使用 weight 的比值作为尺寸比例分配给各个子 View。我们直接在上面的代码中进一步修改,不考虑内嵌的 LinearLayout,对 3 个子 View 添加 weight 属性,并加上背景色方便区分:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:background="#EBA2A2"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#E71B0C"android:text="Here"android:textSize="30sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#E7430F"android:text="Is"android:textSize="30sp" /></LinearLayout><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="2"android:background="#E6D11B"android:text="mybj123"android:textSize="30sp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="3"android:background="#AACCE7"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#88F10D"android:text="Android"android:textSize="30sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#03A9F4"android:text="Study"android:textSize="30sp" /></LinearLayout></LinearLayout>

可以看到,3 个子 View 的高度正好是按照 1:2:3 排列。按照上面给出的计算方法,各个View的高度是 0,所以直接就是按照比例排列。
将高度/宽度写成 0 再使用 weight 属性是最直接最简单的方法,也是最常用最重要的方法,大家今后会经常用到,务必掌握!

4.2 设置成 wrap_content

我们将上面的代码中0dp直接修改成wrap_content再编译,会发现样式好像没有变,比例貌似也是 1:2:3。注意,很多地方会解释成wrap_content也是直接按照weight比例来分配,其实这是大错特错的

三个View的高度大约是 169、285、400,这个比例明显不符合 1:2:3 ,那这个比例是如何计算的呢?
我们再来回顾一下weight计算方式的定义,首先我们根据wrap_content计算高度,那么 3 个子 View 都是单行 size 相同的文字,所以本身高度一样,剩下部分按照 1:2:3 来分配。那么经过测量,单行高度是 54,我们将每个 View 的高度减去 54,得到剩余高度:

第一个View的剩余高度:169 - 54 = 115
第二个View的剩余高度:285 - 54 = 231
第三个View的剩余高度:400 - 54 = 346

这样一来,剩余的尺寸就刚好符合 1:2:3 了。

4.3 设置成 match_parent

match_parent的行为是最诡异的,但是如果理解了wrap_contentmatch_parent也就不难解释,先来看看效果,我们将代码中的wrap_content替换成match_parent.

我们会发现第三块直接消失了,这又是为什么呢?不要慌,我们还是套用一下定义。首先假定父布局高度是 X,那么 match_parent之后每个子View的高度都是 X,这样再按照比例分割剩下的 X - 3X。所以可以得到 3 个子 View 的高度分别是:

第一个View的高度:X + 1/6 * (X-3X) = (2/3)X
第二个View的高度:X + 2/6 * (X-3X) = (1/3)X
第三个View的高度:X + 3/6 * (X-3X) = 0

经过计算,非常合理!

5. 小结

这是大家学习的第一个 Layout,所以对属性的讲解会多也更详细,大家完全不必死记硬背,在今后熟悉了之后会发现其实大部分属性都大同小异。对于 LinearLayout 还有一些其他属性,比如前门提到过的 divider 等等,这个比较简单也比较容易理解,大家完全可以作为课后练习编写代码自行测试。
其实对于 LinearLayout 有很多的局限性,比如它只能按照一行或者一列排列,如果我希望从多个方向去实现布局, LinearLayout 就显得很蹩脚了,接下来一章我们会介绍一种非常灵活的布局,拭目以待。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/786948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于FPGA的HDMI视频接口设计

HDMI介绍 HDMI(High-DefinitionMultimedia Interface)又被称为高清晰度多媒体接口,是首个支持在单线缆上传输,不经过压缩的全数字高清晰度、多声道音频和智能格式与控制命令数据的数字接口。HDMI接口由Silicon Image美国晶像公司倡导,联合索尼、日立、松下、飞利浦、汤姆逊、东…

LLM面面观之MoE

1. 背景 根据本qiang~最新的趋势观察&#xff0c;基于MoE架构的开源大模型越来越多&#xff0c;比如马斯克的Grok-1(314B), Qwen1.5-MoE-A2.7B等&#xff0c;因此想探究一下MoE里面的部分细节。 此文是本qiang~针对大语言模型的MoE的整理&#xff0c;包括原理、流程及部分源码…

Mybatis——查询数据

查询操作 根据用户id查询单条记录&#xff0c;在映射器接口(UserMapper)中定义如下方法&#xff1a; package org.example.mapper;import org.example.demo.User;import java.util.List;public interface UserMapper {//根据id查询UserUser selectUserById(Integer userId); …

对称二叉树_递归_java

对称二叉树 leetcode链接 问题描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 提示&#xff1a; 树中节点数目在范围 [1, 1000] 内 -100 < Node.val < 100 示例 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;…

stable diffusion 的 GPU 不足怎么解决

稳定扩散&#xff08;stable diffusion&#xff09;是一种用于图像处理和计算机视觉任务的图像滤波算法。 当使用Stable Diffusion过程中遇到GPU显示内存不足的问题时。解决这个问题的方法有以下几种&#xff1a; 目前&#xff0c;对我来说&#xff0c;就最后一点能够暂时解决当…

GaussDB云数据库极简版安装与使用-新手指南

一、前言 作为一款领先的企业级数据库管理系统&#xff0c;GaussDB 提供了强大的性能、高度可靠性和丰富的功能&#xff0c;是企业构建可靠、高性能的数据库解决方案的理想选择。 本文主要针对高校和个人测试环境&#xff0c;介绍极简版安装和使用过程&#xff0c;更加适合高…

python多线程简单示例

Python的多线程可以帮助你在同一个进程中运行多个线程&#xff08;即任务&#xff09;&#xff0c;这样可以在执行IO密集型或高延迟的操作时提高程序的效率。下面是一个简单的Python多线程教程。 1. 引入threading模块 Python的threading模块提供了一个简单的方式来创建和管理…

如何在VSCode中高效使用Git:完全指南

引言 在软件开发领域&#xff0c;版本控制是一个至关重要的概念。它不仅仅是一个程序员的工具&#xff0c;更是团队协作、项目管理和代码质量保证的关键。随着软件开发项目的复杂性不断增加&#xff0c;版本控制系统的作用变得愈发显著。 Git作为目前最流行的分布式版本控制系…

SwiftUI Swift 选择图片 添加图片

1. 添加记帐时添加图片功能 2. Show me the code // // TestPhotoPicker.swift // pandabill // // Created by 朱洪苇 on 2024/3/30. //import SwiftUI import PhotosUI import Foundationstruct TestPhotoPicker: View {State private var selectedItem: PhotosPickerIt…

golang语言系列:SOLID、YAGNI、KISS等设计原则

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 golang语言系列 文章&#xff0c;主要对编程通用技能 SOLID、YAGNI、KISS等设计原则 进行学习 1.SOLID设计原则 S&#xff1a;SRP&#xff0c;单一职责原则O&#xff1a;OCP&#xff0c;开闭原则L&#xff1a;…

PCL拟合并绘制平面和柱面(三)

PCL绘制自定义图形 在使用PCL拟合平面和柱面后&#xff0c;需要绘制自定义大小和位置的平面和柱面以便于可视化。 //拟合类型 enum FitType {FitPlane 1, //平面FitCylinder 2 //圆柱 };主要函数&#xff1a; void PointCloudViewer(PointCloudT::Ptr cloudseg, PointC…

Php_Code_challenge12

题目&#xff1a; 答案&#xff1a; 解析&#xff1a; 字符串拼接。

文献阅读:通过 NeuronChat 从单细胞转录组推断神经元-神经元通信

文献介绍 「文献题目」 Inferring neuron-neuron communications from single-cell transcriptomics through NeuronChat 「研究团队」 聂青&#xff08;加利福尼亚大学欧文分校&#xff09; 「发表时间」 2023-02-28 「发表期刊」 Nature Communications 「影响因子」 16.6…

15 - grace序列处理 - 十三点滑动平均法

grace序列处理 -十三点滑动平均法 滑动平均是一种常用的平滑数据的方法,可以用于去除噪声或者提取趋势。十三点滑动平均是指使用窗口大小为13的滑动平均,应用于GRACE序列处理中可以去除周年项的影响。 十三点滑动平均的计算公式为: y [ n ] = ( x [ n − 6 ]

互联网轻量级框架整合之JavaEE基础I

不得不解释得几个概念 JavaEE SUN公司提出来的企业版Java开发中间件&#xff0c;主要用于企业级互联网系统的框架搭建&#xff0c;同时因为Java语言优质的平台无关性、可移植性、健壮性、支持多线程和安全性等优势&#xff0c;其迅速成为构建企业互联网平台的主流技术&#x…

关于Linux系统中Python核心包的重要性和恢复误卸载软件的方法

&#xff08;首发地址&#xff1a;学习日记 https://www.learndiary.com/2024/04/dont-remove-system-python/&#xff09; 大家好&#xff0c;我是来自淘宝网“学习日记小店”的 learndiary&#xff0c;专注于提供 Linux 相关的技术服务。昨日&#xff0c;一位使用 Ubuntu 20…

基于UML的系统分析与设计

统一建模语言(Unified Modeling Language&#xff0c;UML)是一种为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言&#xff0c;是非专利的第三代建模和规约语言。UML是面向对象设计的建模工具&#xff0c;独立于任何具体程序设计语言。 毕业设计是实现本科教学培…

Php_Code_challenge16

题目&#xff1a; 答案&#xff1a; 解析&#xff1a; 所以科学计数法绕过即可。

爬虫 知识点2

article_url url_tag[href]article_response requests.get(article_url, headersheaders)article_soup BeautifulSoup(article_response.content, "html.parser")print(index)&#xff08;1&#xff09;article_url url_tag[‘href’] 这行代码从一个名为url_tag…

Go 源码之切片 Slice

目录 Go 源码之切片 Slice一、总结二、源码&#xff08;一&#xff09;数据结构&#xff08;二&#xff09;创建Slice&#xff08;三&#xff09;append-扩容-growslice&#xff08;四&#xff09;切片深拷贝 Go 源码之切片 Slice go源码之Slice - Jxy 博客 一、总结 slice是…