LinearLayout、RelativeLayout、ConstraintLayout(着重)

Android布局小记

布局系列通用属性

1.android:layout_width="match_parent"

2.android:layout_height="match_parent"

3.android:gravity="" 设置被包裹的空间的位置

4.android:visibility= 显示 visible 不显示,但占空间 invisible 隐藏 gone

5.layout_gravity 设置控件相对于父控件的位置

还有些不怎么很常用的,用的时候再查好了

LinearLayout (线性布局)

LinearLayout 常用在布局嵌套的情况下,控件在布局中可以按照水平或者垂直排列。最好不要设置成wrap_content,这样会导致二次测量(后面源码中有解释)。

特点:控件一定不会出现重叠的情况

基本属性:

1.android:orientation 设置布局的排列方式,水平或者垂直

2.android:layout_weight="1"权值设置,某个控件占布局的多少(linearLayout中控件属性)

注:如果android:orientation设置为horizontal  那么在控件中android:layout_gravity="center_horizontal"无效。(因为布局的排列方式和这种设置时冲突的,举个例子,这就像父母让孩子上学,孩子想去游乐园,结果自然是听父母的) 

案例一,利用LinearLayout实现APP中头布局的效果

      android:layout_width="match_parent"

      android:layout_height="wrap_content"

      android:background="#ccc"

      android:orientation="horizontal">

     

          android:layout_marginLeft="10dp"

          android:layout_gravity="center_vertical"

          android:layout_width="wrap_content"

          android:layout_height="wrap_content"

          android:text="title测试"/>

     

          android:layout_width="30dp"

          android:layout_height="30dp"

          android:layout_marginLeft="250dp"

          android:src="@drawable/ic_launcher_foreground" />

     

          android:layout_marginLeft="10dp"

          android:layout_width="30dp"

          android:layout_height="30dp"

          android:src="@drawable/ic_launcher_foreground" />

 

实现效果:

android:layout_marginLeft="10dp" 这个属性是根据上一个控件的位置计算偏移

案例二:实现每个在布局中均分的效果

      android:layout_width="match_parent"

      android:layout_height="wrap_content"

      android:background="#ccc"

      android:orientation="horizontal">

     

           android:gravity="center"

          android:layout_gravity="center_vertical"

          android:layout_width="0dp"

          android:layout_height="wrap_content"

          android:layout_weight="1"

          android:text="title测试"/>

     

          android:layout_height="30dp"

          android:layout_width="0dp"

          android:layout_weight="1"

          android:src="@drawable/ic_launcher_foreground" />

     

          android:layout_width="0dp"

          android:layout_height="30dp"

          android:layout_weight="1"

          android:src="@drawable/ic_launcher_foreground" />

 

实现效果:

结论:  首先明确一个概念,LinearLayout常在布局嵌套的外层使用,在上面的例子也能看出,在LinearLayout直接放控件实在写起来麻烦,官方也不赞同这么做。

LinearLayout源码简单分析:

对于一个ViewGroup绘制必走的三个流程,onMeasure,onLayout,onDraw,顺着看一下源码是怎么写的

public class LinearLayout extends ViewGroup {

   /** @hide */

   @IntDef({HORIZONTAL, VERTICAL})

   @Retention(RetentionPolicy.SOURCE)

    ......

首先LinearLayout是继承ViewGroup的

然后是出现的是四个构造函数

简单记一下:

第一个构造函数:只有在代码中new的时候调用,官网解释也很简单

第二个构造函数:在xml中使用的时候调用,最常用的一种

第三个构造函数:在xml中,LinearLayout布局中控件有设定style属性,就开始调用第三个构造函数,并有得到结论【结论1】:优先级xml定义>style>theme(本行结论参考https://www.jianshu.com/p/7389287c04bb)

第四个构造函数:我试了几种方案都没有调用,但是上面链接也写了那种情况。

第一步: onMeasure方法

@Override

   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

       if (mOrientation == VERTICAL) {

           measureVertical(widthMeasureSpec, heightMeasureSpec);

       } else {

           measureHorizontal(widthMeasureSpec, heightMeasureSpec);

       }

   }

判断了一下LinearLayout的orientation属性,然后根据orientation写了两个方法,追一个看看

-------------------------------measureVertical()方法干了什么------------------------------------

// See how tall everyone is. Also remember max width.

       for (int i = 0; i < count; ++i) {

           final View child = getVirtualChildAt(i);

           .......

  //根据注释,这一块是看一下每一个控件的高,然后记住最大的宽度。然后获取权重等等

   // 测量模式有三种:

    // * UNSPECIFIED:父控件对子控件无约束

    // * Exactly:父控件对子控件强约束,子控件永远在父控件边界内,越界则裁剪。如果要记忆的话,可以记忆为有对应的具体数值或者是Match_parent

    // * AT_Most:子控件为wrap_content的时候,测量值为AT_MOST。

   //这里获取总权重,当我们设置了总权重则用我们设置的权重值,如果没有设置,则用子控件权重相加的和

    从这里推出**结论** linearLayout的onMeasure进行了两次测量

结论 :    LinearLayout是wrap_content,或者mode为UNSPECIFIED,计算新的mTotalLength,因为这时候所有子控件都是用最大控件的最小值

注:mode为UNSPECIFIED的情况并不常见,LinearLayout 设置的是横向的 但是你的子布局全是充满屏幕 就这点感觉就均分不了的,可能会出现这种情况。

第二步:onMeasure方法。

protected void onLayout(boolean changed, int l, int t, int r, int b) {

       if (mOrientation == VERTICAL) {

           layoutVertical(l, t, r, b);

       } else {

           layoutHorizontal(l, t, r, b);

       }

   }

这一步也有两个方法

第三步:绘制onDraw()

RelativeLayout(相对布局)

相对布局以前是as中默认布局,每个控件都默认在左上角,需要手动设置控件的之间的位置关系

居中属性:

android:layout_centerHrizontal 水平居中

android:layout_centerVertical 垂直居中

android:layout_centerInparent 相对于父控件完全居中

位置调整属性:

android:layout_alignParentBottom 贴紧父控件的下边缘

android:layout_alignParentLeft 贴紧父控件的左边缘

android:layout_alignParentRight 贴紧父控件的右边缘

android:layout_alignParentTop 贴紧父控件的上边缘

android:layout_below 在某控件下方

adroid:layout_above 在某控件上方

android:layout_toLeftOf 在某控件的左边

android:layout_toRightOf 在某控件的右边

android:layout_alignTop 本控件的上边缘和某控件的上边缘对齐

android:layout_alignLeft 本控件的左边缘和某控件的左边缘对齐

android:layout_alignBottom 本控件的下边缘和某控件的下控件对齐

android:layout_alignRight 本控件的右边缘和某控件的有边缘对齐

案例一:同理实现一个title布局

   android:layout_width="match_parent"

   android:layout_height="50dp"

   android:background="#ccc">

  

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_centerVertical="true"

       android:layout_marginLeft="15dp"

       android:text="测试title" />

  

       android:id="@+id/iv_test1"

       android:layout_width="30dp"

       android:layout_height="30dp"

       android:layout_alignParentRight="true"

       android:layout_centerVertical="true"

       android:layout_marginRight="23dp"

       android:src="@drawable/ic_launcher_foreground" />

  

       android:layout_width="20dp"

       android:layout_height="20dp"

       android:layout_marginRight="20dp"

       android:layout_toLeftOf="@id/iv_test1"

       android:layout_centerVertical="true"

       android:src="@drawable/ic_launcher_foreground" />

实现效果:

如果想根据图片上端对齐,只需设置 android:layout_alignTop="@id/iv_test1"

效果如图:

案例二:做一个中间一个大控件、四周小空间控件分别对齐大控件的上下左右四个方向

   android:layout_width="match_parent"

   android:layout_height="match_parent"

  >

  

       android:layout_width="50dp"

       android:layout_height="50dp"

       android:background="#678"

       android:layout_toLeftOf="@+id/rl_big"

       android:layout_alignTop="@id/rl_big"

       >

  

  

       android:layout_width="50dp"

       android:layout_height="50dp"

       android:background="#123"

       android:layout_toRightOf="@+id/rl_big"

       android:layout_alignBottom="@+id/rl_big"

       >

  

  

       android:layout_width="50dp"

       android:layout_height="50dp"

       android:background="#886"

       android:layout_above="@id/rl_big"

       android:layout_alignRight="@id/rl_big"

       >

  

  

       android:layout_width="50dp"

       android:layout_height="50dp"

       android:background="#886"

       android:layout_below="@+id/rl_big"

       android:layout_alignLeft="@id/rl_big"

       >

  

  

       android:id="@+id/rl_big"

       android:layout_width="160dp"

       android:layout_height="160dp"

       android:background="#ccc"

       android:layout_centerInParent="true">

效果图:

ConstraintLayout(限制布局)

RelativeLayout+LinearLayout+x=ConstraintLayout。第一感觉,这个布局好麻烦啊,第二感觉,有点意思,第三感觉,我得好好看看。

可以完全没有嵌套,空间位置完全按照想要的角度去设计 按照牛客网的界面,用ConstraintLayout去实现以下。

属性信息:     

在代码中经常有top bottom start end一些确定位置信息,用一张图来解读,

A控件:start是根布局,也就是parent,top也是指向了根布局,也是parent,只看A控件,如果没有别的设置,那么这两个约束会让它出现在左上角

B控件:start是A,top是c,end是根布局也就是parent,只看b控件,那么它出现的位置一定是A控件的右边 c控件的下面,而且是A控件和右边边界的中间。

ConstraintLayout有一个位置确定,那么其他的控件都可以根据这个控件确定好位置,解决了多层嵌套的问题。

常见为的位置设置信息(选取代码中的一段)

1.app:layout_constraintBottom_toTopOf="@+id/guideline8"  简单理解为在某个空间的底部之上,也就是在谁上面 这个是设置某个控件位置在guideline8之上

2.app:layout_constraintEnd_toEndOf="@+id/textView5" 同理 设置结束位置to结束位置,也就是当前控件和textView5的结束位置相同

3.app:layout_constraintStart_toStartOf="@+id/textView5"设置开始位置to开始位置,意味着开始位置相同

4.app:layout_constraintTop_toTopOf="@+id/guideline7"设置顶部位置为guideline7

5.app:layout_constraintHorizontal_bias="0.0" 水平位置百分比 范围0~1之间,0为原点,1为屏幕最右端。还有一个垂直的,同理

这个代码中 2和3 确定了当前控件与textView5垂直居中对齐。

这些就是大同小异了,不用可以记,根据上面的坐标系想想就ok了

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

工具简单介绍

1.group 用组来控制控件,将iv_title,imageView,iv_test2放到一个组里,然后统一控制。一定要注意,这个不是把控件包裹起来(否则报错:java.lang.ClassCastException: android.support.constraint.Group cannot be cast to android.view.ViewGroup)

      

           android:id="@+id/group"

           android:background="#ff0"

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           app:constraint_referenced_ids="iv_title,imageView,iv_test2" />

2.guildLine 这个帮助布局控件的定位,有两种形式,可以百分比定位也可以dp确认位置,非常灵活

  

       android:id="@+id/guideline8"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal"

       app:layout_constraintGuide_percent="0.65" />

效果图720*1280

效果图1080*2340

效果完美 代码如下

   xmlns:app="http://schemas.android.com/apk/res-auto"

   xmlns:tools="http://schemas.android.com/tools"

   android:layout_width="match_parent"

   android:layout_height="match_parent">

  

       android:layout_width="match_parent"

       android:layout_height="wrap_content"

       android:background="#666">

  

       android:id="@+id/iv_title"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_marginStart="16dp"

       android:layout_marginTop="16dp"

       android:layout_marginEnd="8dp"

       android:text="牛客"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintHorizontal_bias="0.0"

       app:layout_constraintStart_toStartOf="parent"

       app:layout_constraintTop_toTopOf="parent" />

  

       android:id="@+id/imageView"

       android:layout_width="30dp"

       android:layout_height="30dp"

       android:layout_marginEnd="80dp"

       android:src="@mipmap/ic_pixaloop_question"

       app:layout_constraintBottom_toBottomOf="@+id/iv_title"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintLeft_toRightOf="@+id/iv_title"

       app:layout_constraintTop_toTopOf="@+id/iv_title"

       app:layout_constraintVertical_bias="0.5" />

  

       android:layout_width="30dp"

       android:layout_height="30dp"

       android:layout_marginEnd="20dp"

       android:src="@mipmap/ic_pixaloop_question"

       app:layout_constraintBottom_toBottomOf="@+id/imageView"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintLeft_toRightOf="@+id/iv_title"

       app:layout_constraintTop_toTopOf="@+id/imageView"

       app:layout_constraintVertical_bias="0.5" />

  

  

       android:id="@+id/guideline"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="vertical"

       app:layout_constraintGuide_percent="0.66" />


  

       android:id="@+id/guideline2"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal"

       app:layout_constraintGuide_begin="41dp" />


  

       android:id="@+id/frameLayout2"

       android:layout_width="0dp"

       android:layout_height="0dp"

       android:layout_marginStart="8dp"

       android:layout_marginTop="8dp"

       android:layout_marginEnd="8dp"

       android:background="#ccc"

       app:layout_constraintBottom_toTopOf="@+id/guideline3"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintStart_toStartOf="parent"

  app:layout_constraintTop_toTopOf="@+id/guideline2">

      

           android:layout_width="327dp"

           android:layout_height="45dp"

           android:gravity="center"

           android:textColor="@color/txt_selector"

           android:text="ViewPager" />

  

  

       android:id="@+id/guideline3"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal"

       app:layout_constraintGuide_begin="143dp" />

  

       android:id="@+id/guideline4"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal"

       app:layout_constraintGuide_percent="0.3561644" />

  

       android:id="@+id/textView2"

       android:layout_width="wrap_content"

       android:layout_height="20dp"

       android:layout_marginStart="8dp"

       android:layout_marginTop="5dp"

       android:layout_marginEnd="8dp"

       android:layout_marginBottom="8dp"

       android:text="介绍信息"

       app:layout_constraintBottom_toTopOf="@+id/guideline4"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintHorizontal_bias="0.483"

       app:layout_constraintStart_toStartOf="parent"

       app:layout_constraintTop_toTopOf="@+id/guideline3" />

  

       android:id="@+id/guideline5"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="vertical"

       app:layout_constraintGuide_percent="0.33" />

  

       android:id="@+id/guideline7"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal"

       app:layout_constraintGuide_percent="0.5" />

  

       android:id="@+id/guideline8"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal"

       app:layout_constraintGuide_percent="0.65" />

  

       android:id="@+id/textView4"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_marginStart="16dp"

       android:layout_marginTop="8dp"

       android:layout_marginEnd="8dp"

       android:layout_marginBottom="8dp"

       android:text="TextView"

       app:layout_constraintBottom_toTopOf="@+id/guideline7"

       app:layout_constraintEnd_toStartOf="@+id/guideline5"

       app:layout_constraintStart_toStartOf="parent"

       app:layout_constraintTop_toTopOf="@+id/guideline4"

       app:layout_constraintVertical_bias="0.5" />

  

       android:id="@+id/textView5"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:text="TextView"

       app:layout_constraintBottom_toBottomOf="@+id/textView4"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintStart_toStartOf="parent"

       app:layout_constraintTop_toTopOf="@+id/textView4" />

  

       android:id="@+id/textView6"

       android:layout_width="wrap_content"

       android:layout_height="19dp"

       android:layout_marginStart="8dp"

       android:layout_marginEnd="8dp"

       android:text="TextView"

       app:layout_constraintBottom_toBottomOf="@+id/textView5"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintStart_toStartOf="@+id/guideline"

       app:layout_constraintTop_toTopOf="@+id/textView5" />

  

       android:id="@+id/textView7"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_marginTop="8dp"

       android:layout_marginBottom="8dp"

       android:text="TextView"

       app:layout_constraintBottom_toTopOf="@+id/guideline8"

       app:layout_constraintEnd_toEndOf="@+id/textView4"

       app:layout_constraintStart_toStartOf="@+id/textView4"

       app:layout_constraintTop_toTopOf="@+id/guideline7" />

  

       android:id="@+id/textView8"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_marginTop="8dp"

       android:layout_marginBottom="8dp"

       android:text="TextView"

       app:layout_constraintBottom_toTopOf="@+id/guideline8"

       app:layout_constraintEnd_toEndOf="@+id/textView5"

       app:layout_constraintStart_toStartOf="@+id/textView5"

       app:layout_constraintTop_toTopOf="@+id/guideline7"

       app:layout_constraintVertical_bias="0.514" />

  

       android:id="@+id/textView9"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_marginTop="8dp"

       android:layout_marginBottom="8dp"

       android:text="TextView"

       app:layout_constraintBottom_toTopOf="@+id/guideline8"

       app:layout_constraintEnd_toEndOf="@+id/textView6"

       app:layout_constraintStart_toStartOf="@+id/textView6"

       app:layout_constraintTop_toTopOf="@+id/guideline7"

       app:layout_constraintVertical_bias="0.512" />

  

       android:id="@+id/guideline9"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:orientation="horizontal"

       app:layout_constraintGuide_end="50dp" />

  

       android:id="@+id/rgp_bottom_menu"

       android:layout_width="match_parent"

       android:layout_height="wrap_content"

       android:layout_marginTop="8dp"

       android:layout_marginEnd="8dp"

       android:layout_marginBottom="15dp"

       android:gravity="center"

       android:orientation="horizontal"

       app:layout_constraintBottom_toBottomOf="parent"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintStart_toStartOf="parent"

       app:layout_constraintTop_toTopOf="@+id/guideline9">

      

           android:id="@+id/rb_study"

           android:layout_width="0dp"

           android:layout_height="wrap_content"

           android:layout_weight="1"

           android:button="@null"

           android:clickable="true"

           android:textColor="@color/txt_selector"

           android:drawableTop="@drawable/click"

           android:gravity="center"

           android:text="学习" />

      

           android:id="@+id/rb_community"

           android:layout_width="0dp"

           android:layout_height="wrap_content"

           android:layout_weight="1"

           android:button="@null"

           android:textColor="@color/txt_selector"

           android:drawableTop="@drawable/click"

           android:gravity="center"

           android:text="社区" />

      

           android:id="@+id/rb_message"

           android:layout_width="0dp"

           android:layout_height="wrap_content"

           android:layout_weight="1"

           android:button="@null"

           android:textColor="@color/txt_selector"

           android:drawableTop="@drawable/click"

           android:gravity="center"

           android:text="消息" />

      

           android:id="@+id/rb_myNk"

           android:layout_width="0dp"

           android:layout_height="wrap_content"

           android:layout_weight="1"

           android:button="@null"

           android:textColor="@color/txt_selector"

           android:drawableTop="@drawable/click"

           android:gravity="center"

           android:text="我的牛客" />

  

  

       android:id="@+id/button"

       android:layout_width="0dp"

       android:layout_height="0dp"

       android:layout_marginTop="8dp"

       android:layout_marginBottom="8dp"

       android:background="#b5f5f4"

       android:text="我是随便填充的内容"

       app:layout_constraintBottom_toTopOf="@+id/rgp_bottom_menu"

       app:layout_constraintEnd_toEndOf="parent"

       app:layout_constraintStart_toStartOf="parent"

       app:layout_constraintTop_toTopOf="@+id/guideline8" />

几乎没有嵌套,用起来非常爽。

你可能感兴趣的:(LinearLayout、RelativeLayout、ConstraintLayout(着重))