自定义控件之onMeasure
最近一直在接觸自定義控件的知識,自己就嘗試著寫了一個小的demo,算是對自定義知識點進行下總結
今天先來看下自定義控件需要重寫的三個重要方法
看代碼
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);//這兩個方法必須有一個,否則會報錯//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>?
先看下我們的打印結果
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?
從上面的結果我們可以知道xml中控件加載過程
1.xml中使用的控件,加載的時候,調用的是控件兩個參數的方法
public DrawView(Context context, AttributeSet attrs) { }一個是上下文,一個是屬性
2.解析來會調用
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { }方法,這個方法是用來確定控件的寬高的,這個值是從控件的width、height中讀出來的。但是我們發現,這兩個值的打印結果很奇怪,甚至還有負數。網上對此的解釋是
onMeasure傳入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸數值,而是將模式和尺寸組合在一起的數值。
具體什么我也不清楚,不過,它其實是包含了很多信息在里面的。一個就是,從這個數值,我們可以獲得這個控件寬跟高的形式
使用如下方法
int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec);這個mode的取值,可以有一下三種
MeasureSpec.EXACTLY-是精確尺寸,當我們將控件的layout_width或layout_height指定為具體數值時如andorid:layout_width="50dip",或者為FILL_PARENT是,都是控件大小已經確定的情況,都是精確尺寸。
MeasureSpec.AT_MOST 是最大尺寸,當控件的layout_width或layout_height指定為WRAP_CONTENT時,控件大小一般隨著控件的子空間或內容進行 變化,此時控件尺寸只要不超過父控件允許的最大尺寸即可。因此,此時的mode是AT_MOST,size給出了父控件允許的最大尺寸。
MeasureSpec.UNSPECIFIED是未指定尺寸,這種情況不多,一般都是父控件是AdapterView,通過measure方法傳入的模式。
轉載于:https://www.cnblogs.com/zhangshuli-1989/p/vz_custom_15910151.html
總結
以上是生活随笔為你收集整理的自定义控件之onMeasure的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springmvc如何访问静态文件,例如
- 下一篇: iOS 9 学习系列:UIStack V