直接上代码:
/**
* Created by 不告诉你 on 15/8/1.
*/
public class ComPassView extends View {
private Paint markerPaint,textPaint,cirlcePaint;
private String northString,eastString,westString,southString;
private int textHeight;
public ComPassView(Context context) {
super(context);
initCompassView();
}
public ComPassView(Context context, AttributeSet attrs) {
super(context, attrs);
initCompassView();
}
public ComPassView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initCompassView();
}
private void initCompassView(){
setFocusable(true);
cirlcePaint=new Paint(Paint.ANTI_ALIAS_FLAG);
cirlcePaint.setColor(getResources().getColor(R.color.background_color));
cirlcePaint.setStrokeWidth(1);
cirlcePaint.setStyle(Paint.Style.FILL_AND_STROKE);
Resources resources=this.getResources();
northString=resources.getString(R.string.north);
westString=resources.getString(R.string.west);
eastString=resources.getString(R.string.east);
southString=resources.getString(R.string.south);
textPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(getResources().getColor(R.color.text_color));
textHeight= (int) textPaint.measureText("yY");
markerPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
markerPaint.setColor(getResources().getColor(R.color.marker_color));
}
private float bearing;
public float getBearing() {
return bearing;
}
public void setBearing(float bearing) {
this.bearing = bearing;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//指南针是一个填充尽可能多的空间的圆
//通过计算最短的边界高度或者宽度来设置测量的尺寸
int measuredWidth=measure(widthMeasureSpec);
int measuredHeight=measure(heightMeasureSpec);
//得到最小的屏幕宽度作为直径
int radius=Math.min(measuredHeight,measuredWidth);
setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);
}
private int measure(int measureSpec) {
int result=0;
//对测量进行解码
int specMode=MeasureSpec.getMode(measureSpec);
int specSize=MeasureSpec.getSize(measureSpec);
if (specMode==MeasureSpec.UNSPECIFIED){
//没有指定界限就返回默认的大小200
result=200;
}else {
//由于你希望填充可用的空间,所以总是返回整个可用的边界
result=specSize;
}
return result;
}
@Override
protected void onDraw(Canvas canvas) {
//找到空间中心,并将最小长度作为指南针半径存储起来
int px=getMeasuredWidth()/2;
int py=getMeasuredHeight()/2;
int radius=Math.min(px,py);
//绘制背景
canvas.drawCircle(px,py,radius,cirlcePaint);
canvas.save();
//旋转视图,上方对着当前方向
canvas.rotate(-bearing,px,py);
//做标记
int textWidth= (int) textPaint.measureText("W");
int cardinalX=px-textWidth/2;
int cardinalY=py-radius+textHeight;
//每15度绘制一个标记,每45度绘制一个文本。
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){
//每45度绘制文本
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();
}
}
主代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ComPassView comPassView=new ComPassView(this);
setContentView(comPassView);
comPassView.setBearing(45);
}