參考:http://www.cnblogs.com/0616--ataozhijia/p/4003380.html和http://www.open-open.com/lib/view/open1356693446838.html
運行的結果如下:
一.自定義的類繼承view
<pre name="code" class="java">
package com.zhang.customview;
/**
* 複雜的一點自定義控件(onDraw(),onMear())
* zhangwei
*/
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.style.LineHeightSpan.WithDensity;
import android.util.AttributeSet;
import android.view.View;
public class FuZaZiDingYi extends View {
private int mColor=Color.RED;
private Paint mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
public FuZaZiDingYi(Context context) {
super(context);
}
public FuZaZiDingYi(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FuZaZiDingYi(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//重寫onDraw()方法
/**
* onDraw()是個空函數,也就是說具體的視圖都要覆寫該函數來實現自己的顯示(比如TextView在這裏實現了繪製文字的過程)。
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(mColor);
final int paddingLeft=getPaddingLeft();
final int paddingRight=getPaddingRight();
final int paddingTop=getPaddingLeft();
final int paddingBootom=getPaddingLeft();
int width=getWidth()-paddingLeft-paddingRight;//寬
int height=getHeight()-paddingTop-paddingBootom;//高
int radius=Math.min(width, height)/2;
canvas.drawCircle(paddingLeft+width/2,paddingTop +height/2, radius, mPaint);
}
//重寫onMeasure()方法
/**
* 視圖大小的將在這裏最終確定,也就是說onMeasure()方法實現自己的計算視圖大小的方式,
* 並通過setMeasuredDimension(width, height)保存計算結果。
* onMeasure傳入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸數值,而是將模式和尺寸組合在一起的數值。
* mode共有三種情況,取值分別爲MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。
* <一> 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方法傳入的模式。
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode=MeasureSpec.getMode(widthMeasureSpec);//得到模式
int widthSpecSize=MeasureSpec.getSize(widthMeasureSpec);//得到尺寸
int heightSpecMode=MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize=MeasureSpec.getSize(heightMeasureSpec);
if(widthSpecMode==MeasureSpec.AT_MOST && heightSpecMode==MeasureSpec.AT_MOST){
setMeasuredDimension(200, 200);//設置實際大小。
}else if (widthSpecMode==widthSpecMode) {
setMeasuredDimension(200, heightSpecSize);
}else if (heightSpecMode==MeasureSpec.AT_MOST) {
setMeasuredDimension(widthSpecSize, 200);
}
}
}
二.activity_mai'n文件
</pre><pre name="code" class="html"><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=".MainActivity" >
<com.zhang.customview.FuZaZiDingYi
android:id="@+id/zidingyiView"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_margin="20dp"
android:padding="20dp"
android:background="#000000"
android:text="@string/hello_world" />
</RelativeLayout>
三.MainActivity.java什麼都不用寫
package com.zhang.customview;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}