自定义控件之onMeasure
最近一直在接觸自定義控件的知識(shí),自己就嘗試著寫(xiě)了一個(gè)小的demo,算是對(duì)自定義知識(shí)點(diǎn)進(jìn)行下總結(jié)
今天先來(lái)看下自定義控件需要重寫(xiě)的三個(gè)重要方法
看代碼
package com.example.testcode;import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.Log; import android.view.View;public class DrawView extends View {public DrawView(Context context) {super(context);Log.e("123", "drawview_1");// TODO Auto-generated constructor stub }public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);Log.e("123", "drawview_3");// TODO Auto-generated constructor stub }public DrawView(Context context, AttributeSet attrs) {super(context, attrs);Log.e("123", "drawview_2");// TODO Auto-generated constructor stub }@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubint widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);Log.e("123", "MeasureSpec.UNSPECIFIED==" + MeasureSpec.UNSPECIFIED);Log.e("123", "MeasureSpec.AT_MOST==" + MeasureSpec.AT_MOST);Log.e("123", "MeasureSpec.EXACTLY==" + MeasureSpec.EXACTLY);Log.e("123", "widthMeasureSpec===" + widthMeasureSpec);Log.e("123", "heightMeasureSpec===" + heightMeasureSpec);Log.e("123", "widthMode==" + widthMode + " widthSize===" + widthSize);Log.e("123", "heightMode==" + heightMode + " heightSize==="+ heightSize);//這兩個(gè)方法必須有一個(gè),否則會(huì)報(bào)錯(cuò)//super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(75, 75);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right,int bottom) {// TODO Auto-generated method stubLog.e("123", "change===" + changed + " left===" + left + " top==="+ top + " right===" + right + " bottom===" + bottom);super.onLayout(changed, left, top, right, bottom);}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubLog.e("123", "onDraw");super.onDraw(canvas);} }?
xml中使用
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.testcode.MainActivity" ><com.example.testcode.DrawViewandroid:layout_width="100dp"android:layout_height="100dp"android:background="#ff0000" /></RelativeLayout>?
先看下我們的打印結(jié)果
1 09-28 22:53:26.901: E/123(17442): drawview_22 09-28 22:53:26.959: E/123(17442): MeasureSpec.UNSPECIFIED==03 09-28 22:53:26.959: E/123(17442): MeasureSpec.AT_MOST==-21474836484 09-28 22:53:26.959: E/123(17442): MeasureSpec.EXACTLY==10737418245 09-28 22:53:26.959: E/123(17442): widthMeasureSpec===10737419746 09-28 22:53:26.960: E/123(17442): heightMeasureSpec===-21474829587 09-28 22:53:26.960: E/123(17442): widthMode==1073741824 widthSize===1508 09-28 22:53:26.960: E/123(17442): heightMode==-2147483648 heightSize===6909 09-28 22:53:26.960: E/123(17442): MeasureSpec.UNSPECIFIED==010 09-28 22:53:26.960: E/123(17442): MeasureSpec.AT_MOST==-214748364811 09-28 22:53:26.961: E/123(17442): MeasureSpec.EXACTLY==107374182412 09-28 22:53:26.961: E/123(17442): widthMeasureSpec===107374189913 09-28 22:53:26.961: E/123(17442): heightMeasureSpec===107374197414 09-28 22:53:26.961: E/123(17442): widthMode==1073741824 widthSize===7515 09-28 22:53:26.961: E/123(17442): heightMode==1073741824 heightSize===15016 09-28 22:53:27.001: E/123(17442): change===true left===0 top===0 right===75 bottom===7517 09-28 22:53:27.030: E/123(17442): MeasureSpec.UNSPECIFIED==018 09-28 22:53:27.031: E/123(17442): MeasureSpec.AT_MOST==-214748364819 09-28 22:53:27.031: E/123(17442): MeasureSpec.EXACTLY==107374182420 09-28 22:53:27.031: E/123(17442): widthMeasureSpec===107374197421 09-28 22:53:27.031: E/123(17442): heightMeasureSpec===-214748295822 09-28 22:53:27.031: E/123(17442): widthMode==1073741824 widthSize===15023 09-28 22:53:27.031: E/123(17442): heightMode==-2147483648 heightSize===69024 09-28 22:53:27.031: E/123(17442): MeasureSpec.UNSPECIFIED==025 09-28 22:53:27.031: E/123(17442): MeasureSpec.AT_MOST==-214748364826 09-28 22:53:27.031: E/123(17442): MeasureSpec.EXACTLY==107374182427 09-28 22:53:27.032: E/123(17442): widthMeasureSpec===107374189928 09-28 22:53:27.032: E/123(17442): heightMeasureSpec===107374197429 09-28 22:53:27.032: E/123(17442): widthMode==1073741824 widthSize===7530 09-28 22:53:27.032: E/123(17442): heightMode==1073741824 heightSize===15031 09-28 22:53:27.033: E/123(17442): change===false left===0 top===0 right===75 bottom===7532 09-28 22:53:27.045: E/123(17442): onDraw?
從上面的結(jié)果我們可以知道xml中控件加載過(guò)程
1.xml中使用的控件,加載的時(shí)候,調(diào)用的是控件兩個(gè)參數(shù)的方法
public DrawView(Context context, AttributeSet attrs) { }一個(gè)是上下文,一個(gè)是屬性
2.解析來(lái)會(huì)調(diào)用
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { }方法,這個(gè)方法是用來(lái)確定控件的寬高的,這個(gè)值是從控件的width、height中讀出來(lái)的。但是我們發(fā)現(xiàn),這兩個(gè)值的打印結(jié)果很奇怪,甚至還有負(fù)數(shù)。網(wǎng)上對(duì)此的解釋是
onMeasure傳入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸數(shù)值,而是將模式和尺寸組合在一起的數(shù)值。
具體什么我也不清楚,不過(guò),它其實(shí)是包含了很多信息在里面的。一個(gè)就是,從這個(gè)數(shù)值,我們可以獲得這個(gè)控件寬跟高的形式
使用如下方法
int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec);這個(gè)mode的取值,可以有一下三種
MeasureSpec.EXACTLY-是精確尺寸,當(dāng)我們將控件的layout_width或layout_height指定為具體數(shù)值時(shí)如andorid:layout_width="50dip",或者為FILL_PARENT是,都是控件大小已經(jīng)確定的情況,都是精確尺寸。
MeasureSpec.AT_MOST 是最大尺寸,當(dāng)控件的layout_width或layout_height指定為WRAP_CONTENT時(shí),控件大小一般隨著控件的子空間或內(nèi)容進(jìn)行 變化,此時(shí)控件尺寸只要不超過(guò)父控件允許的最大尺寸即可。因此,此時(shí)的mode是AT_MOST,size給出了父控件允許的最大尺寸。
MeasureSpec.UNSPECIFIED是未指定尺寸,這種情況不多,一般都是父控件是AdapterView,通過(guò)measure方法傳入的模式。
轉(zhuǎn)載于:https://www.cnblogs.com/zhangshuli-1989/p/vz_custom_15910151.html
總結(jié)
以上是生活随笔為你收集整理的自定义控件之onMeasure的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: springmvc如何访问静态文件,例如
- 下一篇: iOS 9 学习系列:UIStack V