关闭

Android自定义控件2-简单的写字板控件

标签: android控件
3475人阅读 评论(7) 收藏 举报
分类:

概述

上一篇文章我们对自定义控件进行了一个大体的知识介绍。今天就来学习自定义一个简单的写字板控件。

先来看看效果图

这里写图片描述

就是简单的根据手指写下的轨迹去画出内容

实现

在上一篇文章里提到了android官方给出的自定义控件需要考虑以下几点:

  1. 创建View
  2. 处理View的布局
  3. 绘制View
  4. 与用户进行交互
  5. 优化已定义的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.WritingBoardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        custom:paintColor="@color/colorAccent"
        custom:boardBackground="@color/colorPrimary"
        custom:paintWidth="3dp"/>
</RelativeLayout>

简单的设置了boardBackground、paintWidth和paintColor属性

使用这里只需要注意命名空间,android提供给我们的用android,我们可以自定义我们属性的命名空间
写法为:xmlns:你取的名=”http://schemas.android.com/apk/res-auto”,这里的res-auto可以换成你控件的包名

在XML布局文件中设置的属性要在自定义属性中获取到,所以我们必须实现带有Context, AttributeSet的构造方法

    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) 方法来获取自定义属性和初始化一些信息

通过固定的写法、简单的获取到自定义属性,并且给当前view设置背景、为Paint设置了样式和颜色。完成写字板很重要的就是这里的Path类。

先来介绍一下Path类

看构造方法的注释

/**
 * 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方法来画一些东西。
我们最终的draw就是需要用到drawPath

Path里包含了很多设置几何图形的方法如addRect、addArc。
今天重点说用到的两个方法:

  /**
     * 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方法简单的添加一条上一个点到当前点的线。

有了这两个方法我们就可以实线写字板了

2、处理View的布局

由于这个自定义控件本身就需要一块内容当写字板,所以就不用特别的布局处理了,只是在mode为UNSPECIFIED的时候可能会导致布局显示不出来。

在这里就不进行特殊处理了。

3、绘制View、与用户进行交互

由于该控件本身就需要交互才产生效果,所以之前的两步放在一起考虑了。

上面说到过Canvas有一个drawPath方法。drawPath最后绘制出来什么样其实是看Path里包含的信息。

我们要实现实时显示手写的内容,只需要在滑动的时候获取的坐标通过Path的lineTo方法将线一点一点的连起来。

当手指抬起再落下的时候应该又是一条新的线,所以在落下的时候我们需要调用moveTo方法来为下一条轨迹设置一个起点。

 @Override
    public 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就可以了

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath,mPaint);
    }

总结

其实就是通过手指的触摸事件来控制轨迹的改变,按照固定的模式,一个简单的自定义控件就大功告成啦!

一个简单的写字板就基本完成了,当然你感兴趣可以扩展一下,加上在运行时改变画笔的颜色、画板的颜色。添加字体擦除去的功能。

最后别忘记给我点个赞评论支持下!哈哈

源码下载

12
3
查看评论

Android之使用SurfaceView制作简易写字板

有人说SurfaceView是View的孪生兄弟,其实SurfaceView也是继承自View的,不过View的绘制只能在主线程,而SurfaceView却可以在子线程中进行绘制。本文我们不介绍SurfaceView的基础用法,只介绍如何使用SurfaceView来制作一个简易写字板。PreView...
  • Leavessilent
  • Leavessilent
  • 2017-02-17 23:26
  • 615

Android自定义控件 ----- 基本绘制流程,简单控件的实现

一、自定义控件(一) --- 自定义属性TextView 1,定义属性,制作attrs.xml文件;     属性值: string,color,attr,array,bool,declare-styleable,dimen,drawable,eat-comment,fr...
  • u013205623
  • u013205623
  • 2016-07-18 10:11
  • 4924

Android绘图基础--简易写字板

/** * 自定义一个写字板 * @description:自定义一个控件,实现一个可以手写的效果,后期是要实现刮刮卡抽奖效果,待续…. */ @SuppressLint(“DrawAllocation”) public class WriteView extends View { ...
  • true100
  • true100
  • 2015-12-03 10:09
  • 854

Android 自定义控件开发入门(二)

上一次我们讲了一堆实现自定义控件的理论基础,列举了View类一些可以重写的方法,我们对这些方法的重写是我们继承View类来派生自定义控件的关键 我通过一个最简单的例子给大家展示了这一个过程,无论是多么复杂的自定义控件,思路总是这样子的,但是因为我们仅仅重写了onDraw方法使得大家觉得...
  • sunmc1204953974
  • sunmc1204953974
  • 2014-08-09 16:03
  • 2569

Android常用自定义控件

http://www.see-source.com/androidwidget/list.html
  • zuoliangzhu
  • zuoliangzhu
  • 2015-06-03 12:21
  • 1111

Android自定义控件的实现

简单介绍Android自定义控件的方法和原理,重点还是在于活用。
  • yjp19871013
  • yjp19871013
  • 2017-02-03 20:58
  • 999

android实现自定义控件及如何在其他项目中使用

自定义控件 当android提供的控件不满足需求时, 我们需要自己去定制所需要的控件. 例如在一个TV项目中, 我们需要一种button, 当不选择时, 文本颜色是白色, 当选中时, 文本颜色是黑色, 这时android中自带的button是无法实现的, 那么我们需要去自己定制这种控件. 自定...
  • lbcab
  • lbcab
  • 2016-05-04 16:16
  • 2332

一个类似于windows写字板的程序

  今天写了一个类似windows写字板的程序,使用了RichTextBox控件。拿出来共享一下,也以便以后学习。通过这几天的学习,发现要使用自定义事件的地方还是相当多的。 界面设计代码:namespace RichTextBoxTest{    p...
  • yangshun2008
  • yangshun2008
  • 2008-04-15 12:47
  • 1925

Android 自定义控件开发入门(一)

作为一个有创意的开发者,或者软件对UI设计的要求比较高,你经常会遇到安卓自带的控件无法满足你的需求的情况,这种时候,我们只能去自己去实现适合项目的控件。同时,安卓也允许你去继承已经存在的控件或者实现你自己的控件以便优化界面和创造更加丰富的用户体验。   那么怎样来创建一个新的控件呢?&...
  • sunmc1204953974
  • sunmc1204953974
  • 2014-08-09 15:14
  • 4202

Android自定义控件——自定义组合控件

前面几篇博文介绍了Android如何自定义控件,其实就是讲一下如何“从无到有”的自定义一个全新的控件,继承View或者继承ViewGroup,复写其相关方法,这种自定义控件的方式相对来说难度较大,而且并不是所有需要新控件的情况下,都要这样进行。有很多情况下,我们只要运用好Android给我提供好的控...
  • lee_tianya
  • lee_tianya
  • 2014-09-26 16:42
  • 2611
    个人资料
    • 访问:185686次
    • 积分:2521
    • 等级:
    • 排名:第17188名
    • 原创:48篇
    • 转载:5篇
    • 译文:0篇
    • 评论:194条
    技术交流

    Android技术讨论群

    Java Android开发技术讨论
    博客专栏
    最新评论
    百度统计