zoukankan      html  css  js  c++  java
  • 为什么ConstraintLayout代替其他布局?

    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下载地址


    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的属性设置, 最重要的就是理解属性的表示含义.


    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>

    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>

    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>

    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>

    Ratio

    链样式

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


    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" />

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


    Chains

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

  • 相关阅读:
    实现用户信息的增删改-mongoose数据库操作
    gulp使用流程及常用插件
    Js面向对象动态添加标签页,Tab栏切换
    类似淘宝侧边栏jq代码编写
    jQuery选择器
    jQuery-突出显示案例
    隔行变色加高亮显示
    ajax请求到后台
    LOOK OUT THE HOLE!
    应用keyup监测输入框兼容IE处理
  • 原文地址:https://www.cnblogs.com/vegetate/p/9997209.html
Copyright © 2011-2022 走看看