剖析API Demos中的LabelView

2021-08-27 10:28:13 字數 4154 閱讀 1484

對於谷歌給我們提供的apidemo裡有很多有學習參考價值的例項,今天來學習理解其中的乙個例項類labelview,此類

繼承view,並對view中的onmeasure(),ondraw()方法進行了重寫,其中涉及到setmeasureddimension() ,measurespec,canvas,paint,以及自定義 屬

性的一些應用。

像完全自定義控制項(也就是繼承view自定義控制項),一般會想到覆蓋onmeasure(),ondraw(),

預設onmeasure()會總是設定乙個100*100尺寸

關於自定義屬性 可以參考

android開發之自定義屬性(define custom attributes)

下面是主要實現**

package com.example.labelview;

// class is in a sub-package.

import android.content.context;

import android.content.res.typedarray;

import android.graphics.canvas;

import android.graphics.paint;

import android.util.attributeset;

import android.view.view;

/** * example of how to write a custom subclass of view. labelview

* is used to draw ****** text views. note that it does not handle

* styled text or right-to-left writing systems.

* */

public class labelview extends view

/*** construct object, initializing with any attributes we understand from a

* layout file. these attributes are defined in

* sdk/assets/res/any/classes.xml.

* * @see android.view.view#view(android.content.context, android.util.attributeset)

*/public labelview(context context, attributeset attrs)

// note, if you only care about supporting a single color, that you

// can instead call a.getcolor() and pass that to settextcolor().

// 獲取自定義屬性textcolor的值,並設定文字相應的顏色值

settextcolor(a.getcolor(r.styleable.labelview_textcolor, 0xff000000));

int textsize = a.getdimensionpixeloffset(r.styleable.labelview_textsize, 0);

if (textsize > 0)

// 注意這裡記得要** typedarray

a.recycle();

}// 初始化 paint,並對其設定相應的屬性值

private final void initlabelview()

/*** sets the text to display in this label

* @param text the text to display. this will be drawn as one line.

*/public void settext(string text)

/*** 設定文字大小

* sets the text size for this label

* @param size font size

*/public void settextsize(int size)

/*** 設定文字顏色

* sets the text color for this label.

* @param color argb value for the text

*/public void settextcolor(int color)

/*** 測量view和它的內容,並決定測量寬度和測量高度

* 這個方法被 measure(int, int)所呼叫

*/@override

protected void onmeasure(int widthmeasurespec, int heightmeasurespec)

/*** 決定這個view的寬度

* @param measurespec a measurespec packed into an int

* @return the width of the view, honoring constraints from measurespec

*/private int measurewidth(int measurespec) else

}return result;

}/**

* 決定這個view的高度

* 注意: 字型的高度=上坡度+下坡度+行間距

* ascent和top都是負數

* @param measurespec a measurespec packed into an int

* @return the height of the view, honoring constraints from measurespec

*/private int measureheight(int measurespec) else

}return result;

}/**

* render the text

* 繪製相應的介面,這裡是drawtext

* @see android.view.view#ondraw(android.graphics.canvas)

*/@override

protected void ondraw(canvas canvas)

}

上面**裡涉及到measurespec物件,該物件包含了measure's mode和size兩個屬性:

關於谷歌怎麼把兩個屬性包裝在乙個int裡,怎麼在乙個int裡解包獲取mode和size屬性,請看measurespec原始碼

這樣做可以節約空間,可以減少更多的物件的建立。

public static class measurespec 

public static int getmode(int measurespec)

public static int getsize(int measurespec)

}

onmeasure(intwidthmeasurespec, intheightmeasurespec) 方法, 系統在繪製物件時,首先得確定物件在螢幕上占用多大的範圍,因此在這個方法中,必須得確定好控制項的尺寸然後通過乙個特定的函式介面(setmeasureddimension(width, height))去通知系統有關該控制項的尺寸資訊。系統傳遞進來的兩個引數是乙個約束條件,控制項到底佔據多大的尺寸由這兩個引數決定, 每乙個引數其實乙個measurespec物件,該物件包含了measure's mode和size兩個屬性:

mode

unspecified

系統對物件的size沒進行約束,可以任意設定

exactly

系統對物件的size已經確定,只能為measurespec物件中指定的size

at_most

系統對物件的最大size進行了約束,即該物件的size不能超過measurespec物件中指定的size

參考資料

android中onmeasure初看,深入理解布局之一!

custom components

C 中pictureBox上如何設定label透明

c 中picturebox上如何設定label透明 在picturebox的paint事件中寫下如下 private void picturebox1 paint object sender,painteventargs e 或者在載入頁面的時候在load中寫入下面 picturebox1.send...

C 中的引用剖析

在c語言中,對於下面兩個實現交換變數值的函式,因為函式傳參傳的是函式值,swap1 是完成不了的,而swap2 可以。include void swap1 int a,int b void swap2 int pa,int pb intmain int argc,char ar 執行結果 初始時a ...

雜談 ICS課程中前6個lab的總結

lab 1 位運算 貌似沒什麼好說的,學會svn提交 然後就是智力題了。當時不清楚規則以為有30分是比誰的操作符少,最後幾個人喪心病狂到用離散的知識,語法的順序,簡化操作符,最後總數竟然從120 到了90 最後發現只要下於規定個數就是滿分,sign 不過在簡化的過程中還是略有所得的。lab 2 二進...