很多人都知道Android控件的基本用法,比如Button,CheckBox,progressBar。但是确不知道Button等控件的内部实现原理。前些天上智联招聘上看了一下大公司的对安卓程序的要求。发现高端Android开发,都需要会自定义控件。这里我简单的介绍一下如何自定义一个Android控件。通过自定义控件和动画的配合,可以很容易的实现酷炫的UI
自定义的控件允许当使用者的手指触摸屏幕时进行 UI绘制。这就涉及到如何在View上画一个图形,path,以及如何处理与用户间的交互。
1.基本UI的绘制
首先创建一个继承自View的类:SimpleDrawingView
public class SimpleDrawingView extends View {
public SimpleDrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
创建一个xml的layout布局文件。把我们的自定义控件嵌入其中
public class SimpleDrawingView extends View {
// 设置初始颜色值
private final int paintColor = Color.BLACK;
// defines paint and canvas
private Paint drawPaint;
public SimpleDrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
setupPaint();
}
// 设置颜色和画笔
private void setupPaint() {
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(5);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
}
}
public class SimpleDrawingView extends View {
// ...省略变量和设置Paint的代码
// 画三个圆
@Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(50, 50, 20, drawPaint);
drawPaint.setColor(Color.GREEN);
canvas.drawCircle(50, 150, 20, drawPaint);
drawPaint.setColor(Color.BLUE);
canvas.drawCircle(50, 250, 20, drawPaint);
}
}
效果出来了。So easy是不是。接下来。我们处理控件和用户的交互。
2.处理与用户的交互
这里我们做一个手写输入的UI。其实原理很简单。就是当我们的手指接触屏幕时,在手指的位置进行像上面一样画黑色的实心圆
手指接触屏幕会触发onTouch事件,重写这个方法
public class SimpleDrawingView extends View {
// 设置初始的画笔颜色
private final int paintColor = Color.BLACK;
// 定义画笔和画布
private Paint drawPaint;
//每当手指按下时保存手指位置
private List circlePoints;
public SimpleDrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setupPaint(); //和之前一样
circlePoints = new ArrayList();
}
// 在View上画圆
@Override
protected void onDraw(Canvas canvas) {
for (Point p : circlePoints) {
canvas.drawCircle(p.x, p.y, 5, drawPaint);
}
}
// 当手指移动是追加新位置
@Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
circlePoints.add(new Point(Math.round(touchX), Math.round(touchY)));
// 指示view应该重绘了
postInvalidate();
return true;
}
private void setupPaint() {
// 和上文一样
drawPaint.setStyle(Paint.Style.FILL); // change to fill
// ...
}
}
ok棒棒哒!有的同学可能发现绘制处理的文字不连贯。在下一篇博文中,将会用path来改进