View的基类是一个100乘以100的空白正方形,要改变它,就需要重写onMeasure和onDraw方法。
写一个《android高级编程第三版》中的例子,自定义一个罗盘view:
CompassView.java
package com.godlovesoccer.blogcustomview;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
public class CompassView extends View{
private float bearing;
private Paint markerPaint;
private Paint textPaint;
private Paint circlePaint;
private String northString;
private String southString;
private String westString;
private String eastString;
private int textHeight;
public void setBearing(float _bearing){
bearing=_bearing;
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
}
public float getBearing(){
return bearing;
}
public CompassView(Context context){
super(context);
initCompassView();
}
public CompassView(Context context,AttributeSet attrs,int defaultStyle){
super(context,attrs,defaultStyle);
initCompassView();
}
public CompassView(Context context,AttributeSet attrs){
super(context,attrs);
initCompassView();
}
protected void initCompassView(){
setFocusable(true);
Resources r=this.getResources();
circlePaint=new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setStrokeWidth(1);
circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
northString=r.getString(R.string.cardinal_north);
southString=r.getString(R.string.cardinal_south);
eastString=r.getString(R.string.cardinal_east);
westString=r.getString(R.string.cardinal_west);
textPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(r.getColor(R.color.text_color));
textHeight=(int)textPaint.measureText("yY");
markerPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
markerPaint.setColor(r.getColor(R.color.marker_color));
}
protected void onMeasure(int wMeasureSpec,int hMeasureSpec){
int measuredHeight=measure(hMeasureSpec);
int measuredWidth=measure(wMeasureSpec);
int d=Math.min(hMeasureSpec,wMeasureSpec);
setMeasuredDimension(d,d);
}
private int measure(int measureSpec){
int result=0;
int specMode=MeasureSpec.getMode(measureSpec);
int specSize=MeasureSpec.getSize(measureSpec);
if(specMode==MeasureSpec.UNSPECIFIED){
result=200;
}else// if(specMode==MeasureSpec.EXACTLY)
{
result=specSize;
}
return result;
}
protected void onDraw(Canvas canvas){
int height=getMeasuredHeight();
int width=getMeasuredWidth();
int px=width/2;
int py=height/2;
int radius=Math.min(px, py);
canvas.drawCircle(px, py, radius, circlePaint);
canvas.save();
int textWidth=(int)textPaint.measureText("W");
int cardinalX=px-textWidth/2;
int cardinalY=py-radius+textHeight;
for(int i=0;i<24;i++){
canvas.drawLine(px, py-radius, px, py-radius+10, markerPaint);
canvas.save();
canvas.translate(0, textHeight);
if(i%6==0){
String dirString="";
switch(i){
case 0:{
dirString=northString;
int arrowY=2*textHeight;
canvas.drawLine(px, arrowY, px-5, 3*textHeight, markerPaint);
canvas.drawLine(px, arrowY, px+5, 3*textHeight, markerPaint);
break;
}
case 6:dirString=eastString;break;
case 12:dirString=southString;break;
case 18:dirString=westString;break;
}
canvas.drawText(dirString, cardinalX, cardinalY, textPaint);
}
else if(i%3==0){
String angle=String.valueOf(i*15);
float angleTextWidth=textPaint.measureText(angle);
int angleTextX=(int)(px-angleTextWidth/2);
int angleTextY=py-radius+textHeight;
canvas.drawText(angle, angleTextX, angleTextY, textPaint);
}
canvas.restore();
canvas.rotate(15,px,py);
}
canvas.restore();
}
}