android 测试界面大小,Android view的测量及绘制

view的测量:

首先需要知道的是view的三种测量模式:

1、EXACTLY:精确值模式,当我们对view的layout_width和layout_height属性指定具体的数值的时候,比如layout_width=“100dp”或者指定为match_parent时,系统

进行测量的时候,使用的是这种模式。

2、AT_MOST:最大值模式,当我们对view的layout_width和layout_height属性指定为wrap_content时,即view随着内容的大小变化而变化,或viewgroup随着view的

大小变化而变化,这个时候系统进行测量的时候,使用的是这种模式。

3、UNSPECIFIED:这个属性下不用指定其大小,一般在自定义view时才会使用(这种模式不是很理解,求指教)

在对view进行测量的时候,需要重写onMeasure()方法,view默认的onMeasure()方法只支持EXACTLY模式,即指定具体的数值,所以在自定义view的时候必须重写

onMeasure(),这里留一个疑问:什么时候才会调用Measure方法进行测量?

@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

重写后点super.onMeasure(widthMeasureSpec, heightMeasureSpec);进去看一下源码,发现系统最终会调用这个方法:

setMeasuredDimension(int widthMeasureSpec,int heightMeasureSpec);

这个方法的作用是将我们对view设置的宽和高设置进去,所以我们最终重写的onMeasure()方法就是这个样子的,方法内的两个入参widthMeasureSpec和heightMeasureSpec

就是我们在xml里引用这个view时设置的width和height,后面我们需要根据这两个值进行判断,判断系统要根据什么测量模式进行测量。@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));

}

前文一直在说系统的测量模式,那么我们要怎么样才能获取到系统的测量模式呢?获取测量模式后还需要获取具体的测量大小int specMode = MeasureSpec.getMode(widthMeasureSpec);int specSize = MeasureSpec.getSize(widthMeasureSpec);

单独对measureWidth(widthMeasureSpec)讲解一下,因为height和width是一样的。

copycode.gifprivate int measureWidth(int widthMeasureSpec) {        int widthResult = 0;        int specMode = MeasureSpec.getMode(widthMeasureSpec);        int specSize = MeasureSpec.getSize(widthMeasureSpec);        if (specMode == MeasureSpec.EXACTLY){

widthResult = specSize;

}else {

widthResult = 400;            if (specMode == MeasureSpec.AT_MOST){

widthResult = Math.min(widthResult,specSize);

}

}        return widthResult;

}

copycode.gif

这部分的理解要联系到前面说的3种测量模式,如果是在EXACTLY if (specMode == MeasureSpec.EXACTLY)这种模式下,我们已经在xml里面设置好了具体的数值,所以最后返回的值就是specSize

如果是AT_MOST和UNSPECIFIED这两种测量模式下,我们就需要给view一个默认的大小,因为如果没有给默认的大小的话,系统不知道view的大小,所以view或默认充满父布局。这里默认的大小是400,

大家会发现else里面还有一个if,对AT_MOST这种模式又进行了判断,这是因为在这种模式下,view不需要默认的大小,view的是根据内容的大小变换而变化的。

最后就是xml里面进行引用和效果展示了:

copycode.gif<?xml  version="1.0" encoding="utf-8"?>

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

android:id="@+id/activity_main"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.funny.myapplication.MainActivity">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="View"

android:textSize="20sp"

android:background="#ccf"

android:gravity="center"/>

copycode.gif

(1)android:layout_width="wrap_content"

1024739-20170626183217821-1536989806.png

(2)android:layout_width="match_parent"

1024739-20170626183343039-1834515439.png

(3)android:layout_width="400px"

1024739-20170626183632118-410750390.png

view的绘制:

对view进行绘制需要重写onDraw()方法,onDraw()方法中会有一个canvas,可以把这个参数理解成画板,我们最终会借用这个画板进行绘制。

有了画板,要想绘画的话当然还需要一支画笔paint。

copycode.gif= = ,,,getMeasuredWidth()-,getMeasuredHeight()-,

copycode.gif

接下讲解一下这段代码的功能,首先实例了两只画笔,并且对画笔设置了颜色和风格,接下来开始绘制,这里我们画的是两个相互嵌套的椭圆,

canvas.drawOval(0,0,getMeasuredWidth(),getMeasuredHeight(),paint1);这个方法需要5个入参,分别是view相对于父布局的左、上、右、下的坐标,最后一个是进行绘制的画笔。

系统给我们提供的drawXXX方法有很多:

copycode.gifcanvas绘制的常用方法有:

drawColor() 填充颜色

drawLine() 绘制线

drawLines() 绘制线条

drawOval() 绘制圆

drawPath() 绘制路径

drawPicture() 绘制图片

drawPoint() 绘制点

drawPoints() 绘制点

drawRGB() 填充颜色

drawRect() 绘制矩形

drawText() 绘制文本

drawTextOnPath() 在路径上绘制文本

copycode.gif

效果展示:

1024739-20170626185531914-319917974.png

viewGroup的测量:

我们知道viewGroup管理子view,那么viewGroup的大小,除设置指定大小外,是根据子view来决定的,viewGroup在测量时会遍历所有的子view,调用

子view的Measure方法来获得每一个子view的测量结果,这样文章开始留下的疑问就解决了,意不意外~关于viewGroup的绘制,一般情况下如果不是指定

了viewGroup的背景颜色,viewGroup的onDraw()方法不会被调用,但是viewGroup会使用dispatchDraw()方法来绘制其子view,过程同样是遍历所有的子view

,并调用子view的绘制方法来完成绘制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值