为什么ConstraintLayout代替其他布局-程序员宅基地

技术标签: java  移动开发  

ConstraintLayout, 即约束布局, 在2016年由Google I/O推出. 从支持力度而言, 将成为主流布局样式, 完全代替其他布局, 减少布局的层级, 优化渲染性能. 在新版Android Studio中, ConstraintLayout已替代RelativeLayout, 成为HelloWorld项目的默认布局. ConstraintLayout作为非绑定(Unbundled)的支持库, 命名空间是app:, 即来源于本地的包命名空间. 最新版本是1.0.1(2017.4.21), 在项目的build.gradle中声明.

dependencies {
    compile 'com.android.support.constraint:constraint-layout:1.0.1'
}

本文源码的GitHub下载地址

1240

Constraint Layout

概念

ConstraintLayout约束布局的含义: 根据布局中的其他元素或视图, 确定View在屏幕中的位置, 受到三类约束, 即其他视图, 父容器(parent), 基准线(Guideline).

layout_constraint[本源位置]_[目标位置]="[目标ID]"

例如: 

app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"

约束当前View的底部目标View的底部, 目标View是constraintLayout. 即, 把当前View的底部对齐到constraintLayout的底部.

演示

本例复用的Activity页面, 根据不同的参数设置对应的标题和布局ID.

public class LayoutDisplayActivity extends AppCompatActivity {
    private static final String TAG = LayoutDisplayActivity.class.getSimpleName();
    static final String EXTRA_LAYOUT_ID = TAG + ".layoutId"; // 布局ID

    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTitle(getIntent().getStringExtra(Intent.EXTRA_TITLE));
        final int layoutId = getIntent().getIntExtra(EXTRA_LAYOUT_ID, 0);
        setContentView(layoutId); // 设置页面布局, 复用布局
    }
}

主页面使用ListView展示多项, 每项对应不同的布局页面.

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView list = (ListView) findViewById(R.id.activity_main);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
                android.R.layout.simple_list_item_1, LIST_ITEMS);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                // 复用显示布局
                Intent intent = new Intent(MainActivity.this, LayoutDisplayActivity.class);
                intent.putExtra(Intent.EXTRA_TITLE, LIST_ITEMS[i]); // 标题
                intent.putExtra(LayoutDisplayActivity.EXTRA_LAYOUT_ID, LAYOUT_IDS[i]); // 布局Id
                startActivity(intent);
            }
        });
    }
}

基础

ConstraintLayout最基本的使用方式, 就是指定约束. 如, 取消按钮的底部对齐constraintLayout(父容器)的底部, 左侧对齐父容器的左侧. 下一步按钮的底部对齐父容器的底部, 而左侧对齐取消按钮的右侧, 每个按钮添加Margin空隙.

父容器可以直接指定ID, 也可以使用parent代指.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    android:id="@+id/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="match_parent">

    <Button
        android:id="@+id/cancel_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:layout_marginStart="16dp"
        android:text="取消"
        app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
        app:layout_constraintStart_toStartOf="@id/constraintLayout"/>

    <Button
        android:id="@+id/next_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:layout_marginStart="16dp"
        android:text="下一步"
        app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
        app:layout_constraintStart_toEndOf="@id/cancel_button"/>

</android.support.constraint.ConstraintLayout>

ConstraintLayout的属性设置, 最重要的就是理解属性的表示含义.

1240

Base

比例

ConstraintLayout除了指定约束, 还支持设置比例. Center按钮的全部边界与constraintLayout(父容器)边界对齐, 则为居中. 同时还可以设置水平与竖直的比例, 如Bias按钮, 在对齐父容器后, 设置水平与竖直的比例均为0.25, 表示左侧与右侧比例是1:4, 上部与下部的比例是1:4.

constraintHorizontal_bias设置水平比例, constraintVertical_bias设置竖直比例. 

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/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="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Center"
        app:layout_constraintEnd_toEndOf="@id/constraintLayout"
        app:layout_constraintStart_toStartOf="@id/constraintLayout"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Bias"
        app:layout_constraintEnd_toEndOf="@id/constraintLayout"
        app:layout_constraintStart_toStartOf="@id/constraintLayout"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintHorizontal_bias="0.25"
        app:layout_constraintVertical_bias="0.25"/>

</android.support.constraint.ConstraintLayout>

1240

Bias

引导线

ConstraintLayout除了与视图约束以外, 还支持与引导线(Guideline)约束. 如, 设置竖直引导线(Guideline)距离左侧72dp. 两个按钮的左侧都与引导线约束, 上下使用比例方式排列, 一个是0.25, 一个是0.75.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/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="match_parent">

    <android.support.constraint.Guideline
        android:id="@+id/guideLine"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="72dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Guide Up"
        app:layout_constraintStart_toStartOf="@id/guideLine"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintVertical_bias="0.25"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Guide Down"
        app:layout_constraintStart_toStartOf="@id/guideLine"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintVertical_bias="0.75"/>

</android.support.constraint.ConstraintLayout>

1240

Guide Line

视图尺寸

ConstraintLayout也支持自动填充宽高, 把宽高设置为0dp会根据位置自动填充. 如, Large按钮, 左侧与Small按钮的左侧对齐, 右侧与constraintLayout(父控件)的右侧对齐, 宽度设置为0dp, 则会填充全部空位.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    android:id="@+id/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="match_parent">

    <Button
        android:id="@+id/small"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Small"
        app:layout_constraintStart_toStartOf="@id/constraintLayout"
        app:layout_constraintTop_toTopOf="@id/constraintLayout"/>

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Large"
        app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
        app:layout_constraintEnd_toEndOf="@id/constraintLayout"
        app:layout_constraintStart_toEndOf="@id/small"
        app:layout_constraintTop_toTopOf="@id/constraintLayout"/>

</android.support.constraint.ConstraintLayout>

1240

Measure

纵横比

ConstraintLayout支持使用constraintDimensionRatio设置宽高的纵横比, 把宽(layout_width)或者高(layout_height)设置为0dp, 则根据另一个属性值和比例, 计算当前属性值.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    android:id="@+id/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="match_parent">

    <ImageView
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:background="@color/colorAccent"
        android:src="@drawable/total_large"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintLeft_toLeftOf="@+id/constraintLayout"
        app:layout_constraintRight_toRightOf="@+id/constraintLayout"
        app:layout_constraintTop_toTopOf="@+id/constraintLayout"
        app:layout_constraintDimensionRatio="16:9"/>

    <ImageView
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:background="@color/colorAccent"
        android:contentDescription="@null"
        android:src="@drawable/total_large"
        app:layout_constraintBottom_toBottomOf="@+id/constraintLayout"
        app:layout_constraintDimensionRatio="4:3"
        app:layout_constraintLeft_toLeftOf="@+id/constraintLayout"
        app:layout_constraintRight_toRightOf="@+id/constraintLayout"/>

</android.support.constraint.ConstraintLayout>

1240

Ratio

链样式

ConstraintLayout同时支持链样式, 这与LinearLayout的layout_weight属性非常类似, 通过设置不同的样式排列元素.

1240

Chain

app:layout_constraintHorizontal_chainStyle设置水平链.

<TextView
    android:id="@+id/property_tv_cst_aries"
    style="@style/MemberWidget.Constellation"
    android:layout_marginLeft="@dimen/spacing_big"
    android:layout_marginTop="@dimen/spacing_medium"
    android:onClick="@{listener::onConstellationSelected}"
    android:text="白"
    app:layout_constraintHorizontal_chainStyle="spread_inside"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/property_tv_cst_taurus"
    app:layout_constraintTop_toBottomOf="@id/property_tv_constellation" />

通过不同的链式组合, 生成复杂的视图样式.

1240

Chains

ConstraintLayout的基本使用方式就是这些, 兼顾LinearLayout与RelativeLayout的优点, 非常适合构建复杂布局, 降低布局的层级, 加快渲染速度.

转载于:https://my.oschina.net/dccjll/blog/1036415

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34138521/article/details/91761661

智能推荐

svn迁移git 保留提交记录_svn转git,提交记录-程序员宅基地

文章浏览阅读116次。useradd git #创建名称为git的用户passwd git #git用户对应的密码也为git创建git仓库mkdir /home/git/gitrepocd /home/git/gitrepogit init --bare test.gitchown -R git:git test.git第四步:开始将svn代码做迁移操作,在windows上任意创建一个空文件夹GitTest,作为一个Git本地仓库,用来存放从SVN上迁移过来的代码。第五步:在这个文件中打开Git Bas._svn转git,提交记录

Autoware的MPC源码解析(三)mpc_follower解析:车辆模型介绍_车辆动力学误差方程mpc-程序员宅基地

文章浏览阅读3.6k次,点赞4次,收藏27次。版权声明:本文为博主原创文章,未经博主允许不得转载。源码地址:https://gitlab.com/autowarefoundation/autoware.ai/autoware/wikis/Source-Build如有错误或建议,欢迎提出。在Autoware的mpc源码中使用了三种车辆模型,本篇主要对这三种车辆模型进行解析。1车辆运动学误差模型(no delay)..._车辆动力学误差方程mpc

MMO即时战斗:技能实现_mmo的实时战斗和slg结合-程序员宅基地

文章浏览阅读9.4k次,点赞4次,收藏28次。一、前言 基本所有MMO游戏无论是回合制、策略类、即时战斗等等类型都需要有相应的技能系统,所以技能系统有一定的通用性和可复用性,但每种类型的游戏也会有自己的特点,不过万变不离其宗,本文结合自己参与开发并在公网运营两年以上的两款游戏,分别为一款SLG策略游戏和一款即时战斗类游戏,阐述下技能系统的实现方法,方法并不是最优的,但已经实现并经过外网运营几年时间的检验,相信_mmo的实时战斗和slg结合

yii2 修改及批量修改_yii2 批量修改-程序员宅基地

文章浏览阅读5.5k次。使用model::save()进行修改$user = User::find()-&gt;where(['name'=&gt;'test'])-&gt;one(); //获取name等于test的模型$user-&gt;age = 40; //修改age属性值$user-&gt;save(); //保存直接修改:修改用户test的年龄为40$result = User::m..._yii2 批量修改

IDOC的debug、错误处理和各项IDOC信息查询(各种查询,全)。_idoc debug-程序员宅基地

文章浏览阅读1.2w次,点赞2次,收藏20次。待定_idoc debug

一篇讲透Java重构之道_java项目功能重构的原理-程序员宅基地

文章浏览阅读303次。前言“重构” 这个词对于大部分工程师来说都不陌生。实际上大部分人都只是 “听得多做得少”,真正进行过代码重构的人不多,而把持续重构作为开发的一部分的人,就更是少之又少了。一方面,重构代码对一个工程师能力的要求,要比单纯写代码高得多。重构需要你能洞察出代码存在的坏味道或者设计上的不足,并且能合理、熟练地利用设计思想、原则、模式、编程规范等理论知识解决这些问题。另一方面,很多工程师对为什么要重构、到底重构什么、什么时候重构、又该如何重构等相关问题理解不深,对重构没有系统性、全局性的认识,面对一堆烂代码,没_java项目功能重构的原理

随便推点

计算机视觉-神经网络与BP算法_计算机视觉结合bp神经网络24小时监测工艺及设备-程序员宅基地

文章浏览阅读947次。神经网络定义大量(结构简单、功能接近)的神经元节点按一定体系架构连接成的网状结构。作用分类模式识别连续值预测目标建立输入与输出的映射关系神经元模型定义每个神经元都是一个结构相似的独立单元,它接受前一层传来的数据,并将这些数据的加权输入非线性作用函数中,最后将非线性作用函数的输出结果传递给后一层。非线性函数f称为激活函数。激活函数上图为两种激活函数,分别为sig..._计算机视觉结合bp神经网络24小时监测工艺及设备

java ReplaceAll 以及 分组_java的replace替换第一个分组-程序员宅基地

文章浏览阅读3.5k次。java ReplaceAll 以及 分组java 的replaceAll方法是对整个字符串满足条件的进行替换,可以用正则表达式。比如 String s1="My name is Khan. My name is Bob. My name is Sonoo."; String replaceString=s1.replaceAll("\\s",""); System.out.p..._java的replace替换第一个分组

亲测~Win10开启系统自带Wifi热点步骤_win10命令行 软件控制wifi开关-程序员宅基地

文章浏览阅读1.2w次。本文记录如何用命令行开启Win10自带的wifi热点。1)以管理员身份打开命令提示符,输入“netsh wlan show drivers”,找到“支持的承载网络”一项,如果为“是”,说明电脑支持开启wifi热i点,可继续下面的步骤。2)接着输入“netsh wlan set hostednetwork mode=allow ssid=wifi名称 key=wifi密码”。3)接着输入_win10命令行 软件控制wifi开关

Centos6.8_x86_64安装使用 Informix11.70 数据库_iif.11.70.fc8de.linux-x86_64.taranzhuangbao-程序员宅基地

文章浏览阅读6.1k次。Informix是IBM公司出品的关系数据库管理系统(RDBMS)家族。作为一个集成解决方案,它被定位为作为IBM在线事务处理(OLTP)旗舰级数据服务系统。_iif.11.70.fc8de.linux-x86_64.taranzhuangbao

Android复习练习十一(ListView列表显示使用BaseAdapter以及ListView动态刷新)_android baseadapter getview 动态更新view-程序员宅基地

文章浏览阅读2.7k次。需求:结合SQLite数据库,实现一个取_android baseadapter getview 动态更新view

Siebel EAI: Siebel Fusion EAI Outbound Web Service-程序员宅基地

文章浏览阅读109次。ScenarioThis document presents how to deploy an outbound WS to WLS and how to execute testing using Siebel Simulator Toolkit.Deploy Outbound WS to WLS1. Open your JDev and go to File &gt; New &g..._eai outbound

推荐文章

热门文章

相关标签