
就是简单的根据手指写下的轨迹去画出内容
一、实现
之前一篇文章里提到了android官方给出的自定义控件需要考虑以下几点:
创建View
处理View的布局
绘制View
与用户进行交互
优化已定义的View
就按照这个步骤来完成今天的自定义控件
1、创建View
上篇提到创建View这一步的时候要考虑的就是很简单的自定义属性的声明、使用。
今天的控件可以有一些什么自定义属性呢?要实现写字板,其实就是三个东西:写字板的颜色、笔的颜色、笔的粗细。所以接下来自定义属性。
<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="WritingBoardView"><attr name="boardBackground" format="color"></attr> <!--画板颜色--><attr name="paintColor" format="color"></attr> <!--画笔颜色--><attr name="paintWidth" format="dimension"></attr> <!--画笔宽度--></declare-styleable></resources>定义了就是为了要使用
<?xml version="1.0" encoding="utf-8"?><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"xmlns:custom="http://schemas.android.com/apk/res-auto"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.qiangyu.test.writingboardview.MainActivity"><com.qiangyu.test.writingboardview.view.WritingBoardViewandroid:layout_width="match_parent"android:layout_height="match_parent"custom:paintColor="@color/colorAccent"custom:boardBackground="@color/colorPrimary"custom:paintWidth="3dp"/></RelativeLayout>简单的设置了boardBackground、paintWidth和paintColor属性
private int mBoardBackground;//画板颜色private int mPaintColor;//画笔颜色private int mPaintWidth;//画笔宽度private Path mPath;private Paint mPaint;//画笔public WritingBoardView(Context context) {this(context,null);}public WritingBoardView(Context context, AttributeSet attrs) {this(context, attrs,0);}public WritingBoardView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context,attrs);} private void init(Context context,AttributeSet attrs) {TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.WritingBoardView);mBoardBackground =a.getColor(R.styleable.WritingBoardView_boardBackground,Color.WHITE);mPaintColor =a.getColor(R.styleable.WritingBoardView_paintColor,Color.BLUE);mPaintWidth = a.getDimensionPixelSize(R.styleable.WritingBoardView_paintWidth,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,5,getResources().getDisplayMetrics()));a.recycle();mPaint = new Paint();mPath = new Path();setBackgroundColor(mBoardBackground);mPaint.setColor(mPaintColor);mPaint.setStrokeWidth(mPaintWidth);mPaint.setStyle(Paint.Style.STROKE);mPaint.setAntiAlias(true);}上面代码确保了每个构造方法最终都调用了第三个构造方法里的init(context,attrs) 方法来获取自定义属性和初始化一些信息/** * The Path class encapsulates compound (multiple contour) geometric paths * consisting of straight line segments, quadratic curves, and cubic curves. * It can be drawn with canvas.drawPath(path, paint), either filled or stroked * (based on the paint"s Style), or it can be used for clipping or to draw * text on a path. */public class Path {...} 大体就是说Path封装了由了直线和各种曲线组成几何图形信息。我们可以调用canvas通过drawPath方法来画一些东西。 /** * Set the beginning of the next contour to the point (x,y). * * @param x The x-coordinate of the start of a new contour * @param y The y-coordinate of the start of a new contour */public void moveTo(float x, float y) {native_moveTo(mNativePath, x, y);} moveTo方法就是设置下一个连线或者图形最开始的位置。/** * Add a line from the last point to the specified point (x,y). * If no moveTo() call has been made for this contour, the first point is * automatically set to (0,0). * * @param x The x-coordinate of the end of a line * @param y The y-coordinate of the end of a line */public void lineTo(float x, float y) {isSimplePath = false;native_lineTo(mNativePath, x, y);} lineTo方法简单的添加一条上一个点到当前点的线。 @Overridepublic boolean onTouchEvent(MotionEvent event) {float touchX = event.getX();float touchY = event.getY();switch (event.getAction()){case MotionEvent.ACTION_DOWN:mPath.moveTo(touchX,touchY);//重新设置即将出现的线的起点break;case MotionEvent.ACTION_MOVE:mPath.lineTo(touchX,touchY);//连线break;case MotionEvent.ACTION_UP:break;}invalidate();//通知系统重绘return true;//要处理当前事件}在onTouch中return true表示要处理当前事件。并且在每一次操作调用invalidate来绘制界面,我们的onDraw 方法只需要简单的调用drawPath就可以了 @Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawPath(mPath,mPaint);}总结