关于自定义View时代使用样式,风格,大小的资源定义不再介绍,这里注重介绍如何在onDraw(Canvas canvas)方法中去绘制所需要的VIew。
主要体现在 Paint 、Canvas对象的使用:
下面主要呈现一个类似手表的View的绘制:
自定义View如下:
package view;
import com.example.testtone.MainActivity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
public class TestView extends View {
Paint p;
Paint drawP;
Paint tp;
float mStrokeWidth = 10;
private int second = 0;
float radius = 300f;
public TestView(Context context) {
super(context);
// TODO Auto-generated constructor stub
mStrokeWidth = 6f * getResources().getDisplayMetrics().density;
p = new Paint();
p.setColor(Color.YELLOW);
p.setStrokeWidth(6);
drawP = new Paint();
drawP.setColor(Color.RED);
drawP.setStrokeWidth(mStrokeWidth);
tp = new Paint();
tp.setColor(Color.BLUE);
tp.setStrokeWidth(mStrokeWidth);
p.setAntiAlias(true);
p.setStyle(Style.STROKE);
drawP.setAntiAlias(true);
drawP.setStyle(Style.STROKE);
}
public void updateTime(int second){
this.second = second;
this.invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
//
// Log.d("jxh"," onDraw mStrokeWidth="+mStrokeWidth);
// RectF rf = new RectF(mStrokeWidth,mStrokeWidth,getWidth()*2/3,getWidth()*2/3);
// canvas.drawArc(rf, (float)-90, (float)360, false, p);
// canvas.drawArc(rf, (float)-90, (float)180, false, drawP);
//
// tp.setTextSize(24);
// canvas.drawText("50%" , mStrokeWidth+getWidth()/3, mStrokeWidth+getWidth()/3, tp);
canvas.translate(getWidth()/2, getWidth()/2); //将位置移动画纸的坐标点:150,150
canvas.drawCircle(0, 0, radius, p); //画表圆圈
// canvas.save();和canvas.restore();是两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的。
// 画字符串信息
canvas.save();
canvas.translate(-240, -240);
Path path = new Path();
path.addArc(new RectF(0,0,480,480), -180, 180);
Paint citePaint = new Paint(p);
citePaint.setTextSize(28);
citePaint.setStrokeWidth(1);
citePaint.setColor(Color.BLUE);
// 第三个参数调整 字符串在path上的起始位置偏移量;第四个参数调节+-偏离path的远近距离,正数向path内侧偏移
canvas.drawTextOnPath("welecom to come Xuehao home", path,180, 60, citePaint);
canvas.restore();
Paint tmpPaint = new Paint(p); //小刻度画笔对象
tmpPaint.setStrokeWidth(1);
tmpPaint.setColor(Color.RED);
tmpPaint.setTextSize(28);
int count = 60; //总刻度数
canvas.rotate(180,0f,0f); //旋转调整刻度显示位置0位于最上方
for(int i=0 ; i <count ; i++){
if(i%5 == 0){
canvas.drawLine(0f, radius, 0, radius-40f, p);
canvas.drawText(String.valueOf(i/5), -8f, radius-50f, tmpPaint);
}else{
canvas.drawLine(0f, radius, 0f, radius -25f, tmpPaint);
}
canvas.rotate(6,0f,0f); //旋转画纸
}
//绘制指针圆心
tmpPaint.setColor(Color.GRAY);
tmpPaint.setStrokeWidth(4);
canvas.drawCircle(0, 0, 15, tmpPaint);
tmpPaint.setStyle(Style.FILL);
tmpPaint.setColor(Color.YELLOW);
canvas.drawCircle(0, 0, 10, tmpPaint);
//绘制指针,Y: 上负,下正;; X: 左 负,右正
float r =30;
float R = 200;
double xEnd,xStart,yEnd,yStart;
// 根据三角函数计算
double angle = second*Math.PI/30;
Log.d("jxh"," onDraw mStrokeWidth="+mStrokeWidth);
Toast.makeText(this.getContext(), " angle= "+angle, Toast.LENGTH_SHORT).show();
xStart = -r*Math.sin(angle);
yStart = r*Math.cos(angle);
xEnd = R*Math.sin(angle);
yEnd = -R*Math.cos(angle);
canvas.drawLine((float)xStart,(float) yStart,(float) xEnd,(float)yEnd,p );
}
}
主Activity的:
package com.example.testtone;
import view.TestView;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends Activity {
private int DELYED= 1000;
Handler mHandler =new Handler();
public int seconds =0;
Runnable runnable = new Runnable() {
@Override
public void run() {
// handler自带方法实现定时器
try {
if(seconds <= 60){
tv.updateTime(seconds);
seconds++;
}else{
seconds=0;
tv.updateTime(seconds);
seconds++;
}
mHandler.postDelayed(this, DELYED);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("exception...");
}
}
};
TestView tv ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TestView(this);
setContentView(tv);
mHandler.postDelayed(runnable, DELYED); //每隔1s执行
}
}