Android View系列(三)——LinearLayout源码分析


title: Android View系列(三)——LinearLayout源码分析
tag: Android源码
category: Android
date: 2019-04-29


LinearLayout 源码分析

简介

LinearLayout是我们开发中最常用的布局之一了,就是我们所说的线程布局,其分水平(HORIZONTAL)和垂直(VERTICAL)两个方向进行布局,接下来我们就慢慢看看这个LinearLayout

首先看看类的继承关系

public class LinearLayout extends ViewGroup {
   
	...
}

很明显,直接继承自ViewGroup,当然,其他常用的布局RealativeLayout、FrameLayout等都是直接继承ViewGroup的

接着简单看看LinearLayout中的一些属性吧

//水平方向和垂直方向
   public static final int HORIZONTAL = 0;
   public static final int VERTICAL = 1;
//几种分割线的状态
   //不展示dividers
   public static final int SHOW_DIVIDER_NONE = 0;
   //展示dividers在group的前面
   public static final int SHOW_DIVIDER_BEGINNING = 1;
   //给viewgroup的每一个item之间都展示divider
   public static final int SHOW_DIVIDER_MIDDLE = 2;
   //展示在ViewGroup的后面
   public static final int SHOW_DIVIDER_END = 4;
...
   //基线对齐变量
   @ViewDebug.ExportedProperty(category = "layout")
   private boolean mBaselineAligned = true;
//基线对齐对象index
   @ViewDebug.ExportedProperty(category = "layout")
   private int mBaselineAlignedChildIndex = -1;
//基线的额外偏移量
   @ViewDebug.ExportedProperty(category = "measurement")
   private int mBaselineChildTop = 0;
//方向
   @ViewDebug.ExportedProperty(category = "measurement")
   private int mOrientation;
...
   //对齐方式
   private int mGravity = Gravity.START | Gravity.TOP;
//整个LinearLayout子View的高度和(Vertical)或者宽度和(Historical)
   @ViewDebug.ExportedProperty(category = "measurement")
   private int mTotalLength;
//权重和
   @ViewDebug.ExportedProperty(category = "layout")
   private float mWeightSum;
//权重最小尺寸对象
   @ViewDebug.ExportedProperty(category = "layout")
   private boolean mUseLargestChild;
//基线对齐相关
   private int[] mMaxAscent;
   private int[] mMaxDescent;

   private static final int VERTICAL_GRAVITY_COUNT = 4;
//几种index
   private static final int INDEX_CENTER_VERTICAL = 0;
   private static final int INDEX_TOP = 1;
   private static final int INDEX_BOTTOM = 2;
   private static final int INDEX_FILL = 3;
//分割线相关
   private Drawable mDivider;
   private int mDividerWidth;
   private int mDividerHeight;
   private int mShowDividers;
   private int mDividerPadding;

   private int mLayoutDirection = View.LAYOUT_DIRECTION_UNDEFINED;

属性简单就看这么多吧,接着进入重点吧,看看LinearLayout是怎么测量、布局、绘制的

onMeasure

@Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   
       if (mOrientation == VERTICAL) {
   
           measureVertical(widthMeasureSpec, heightMeasureSpec);
       } else {
   
           measureHorizontal(widthMeasureSpec, heightMeasureSpec);
       }
   }

在onMeasure方法中,对方向进行了判断,来决定是垂直测量还是横向测量,我们就看垂直方向的吧

由于方法有点长,分几个部分一点一点看吧,先看这个函数内的一些变量吧

void measureVertical(int widthMeasureSpec, int heightMeasureSpec) {
   
       //每次测量都会将ziView的高度和进行初始化
       mTotalLength = 0;
       //子View最大宽度,不包括含有layout_weight权重的子View
       int maxWidth = 0;
       //测量状态
       int childState = 0;
       //子View中layout_weight <= 0的最大高度
       int alternativeMaxWidth = 0;
       //子View中layout_weight > 0的最大高度
       int weightedMaxWidth = 0;
       //是否全是match_parent
       boolean allFillParent = true;
       //子View权重和
       float totalWeight = 0;
	//子View个数
       final int count = getVirtualChildCount();
	//测量模式
       final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
       final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
	//为match_parent时未true
       boolean matchWidth = false;
       boolean skippedMeasure = false;
	//基线对齐的对象index
       final int baselineChildIndex = mBaselineAlignedChildIndex;
       //权重最小尺寸对象
       final boolean useLargestChild = mUseLargestChild;
       //子View中最高高度
       int largestChildHeight = Integer.MIN_VALUE;
       int consumedExcessSpace = 0;
       //能够显示的View个数
       int nonSkippedChildCount = 0;
       ...
   }

这些变量大致的意思都写在代码注释里了,简单过一下就ok了

接着看看方法内的后面一部分,测量所有的子View

void measureVertical(int widthMeasureSpec, int heightMeasureSpec) {
   
	...
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值