【android开发】手写签名系统的设计与实现之实现手写画板(三)

在上一篇文章中,我们介绍了如何解析pdf文件,并显示在手机页面上。接下来我们将介绍一下,如何实现一个手写画板,主要用到的类有画布类canvas和画笔了paint。先看看效果

               画板界面                                          设置画笔界面

           

一、画板的实现原理:

我们通过类canvas类实现画板,通过paint类来实现画笔,笔和布都有了,我们就可以来写东西了。

我们首先是通过自定义一个view控件,即新建一个类HandWritingView去继承View,在里面将画布和画笔创建好,最后在布局文件中创建控件即可。

第一步:新建一个类HandWriting,并继承View

public class HandWritingView extends View 
继承View后我们要复写两个方法onDraw()和onTouchEvent(),接下来的操作就是在两个方法中实现画布和画笔。之前一个哥们说他去面试,面试官问他实现画布时,在onDraw()和onTouchEvent()方法中是做什么工作,今天正好在这里和大家聊聊,我们通常实现一个功能很顺手,如果问我们一些细节问题,我们可能就说不上了,难免面试官回说我们都是复黏贴代码。

首先说说onDraw(),根据名称我们就能知道,这里是实现绘画的,对的,就是实现绘画功能的,创建画布canvas和画笔paint以及设置画布和画笔的属性都是这里,当然了我们还是把监听的轨迹传递过来,画笔才能去书写。

@SuppressLint("DrawAllocation") 
    @Override 
    protected void onDraw(Canvas canvas) { 
        super.onDraw(canvas); 
        canvas.clipRect(0, 50, 720, 360);//控制画板的区域坐标(x,y,x+width,y+high);
        canvas.drawColor(Color.argb(150, 120, 120, 120));//控制画板的背景颜色
        canvas.drawBitmap(HandWriting(new1Bitmap), 0, 0, null);
        canvas.drawPath(path, paint);
    } 
 
    /**
     * 功能:完成画笔的操作,并返回bitmap对象
     * @param originalBitmap
     * @return
     */
    @SuppressLint("HandlerLeak") 
 
    public  Bitmap HandWriting(Bitmap originalBitmap) { 
        
    	if (isClear) { 
            canvas = new Canvas(new2Bitmap); 
        } else { 
            canvas = new Canvas(originalBitmap); 
        }
        paint = new Paint();
        paint.setColor(color); //设置画笔的颜色
        paint.setStyle(Style.STROKE); 
        paint.setStrokeWidth(strokeWidth);//设置画笔的粗细
        paint.setAntiAlias(true);//抗锯齿
        paint.setDither(true);
        paint.setFilterBitmap(true);
        paint.setSubpixelText(true);  
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);
        if (isClear) { 
            return new2Bitmap; 
        } 
        return originalBitmap; 
    } 
    
通过上面的代码我们就把画布和画笔实例出来了,当然了其中的path我们还没有进行配置,这样我们是不能去书写的,没有响应的轨迹,笔就不会显示出效果。轨迹的处理就要放在onTouchEvent()方中了,对轨迹的处理有两种方法:一种是线性处理,利用lineTo;另一种是贝尔曲线,利用quadTo。对于书写字的画板,当然后者是最好的了,这样实现起来的效果会更加的平滑和流畅。在ontouchEvent()方法中获取三个动作,按下屏幕、滑动屏幕、离开屏幕。按下时,记住当前的屏幕坐标,滑动记录轨迹,离开时清空之前的轨迹。这样,我们就能保证书写的平滑和流畅了。看代码:

/**
     * 功能:完成对画笔路径的操作,为了保证画笔效果的光滑性,采用贝尔曲线法
     */
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
        startX = event.getX(); 
        startY = event.getY();
        switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			touchDown(event);
			return true;
		case MotionEvent.ACTION_MOVE:
			touchMove(event);
			return true;
		case MotionEvent.ACTION_UP:
			touchUp(event);
			return true;
		default:
			break;
		}
       
        return super.onTouchEvent(event); 
    } 
    
    /**
     * 功能:手指点下屏幕时调用  
     * @param event
     */
    private void touchDown(MotionEvent event){  
    	clickX = startX;
    	clickY = startY;
    	//path绘制的绘制起点 
    	path.moveTo(startX, startY);
        invalidate(); 
    }
    
    /**
     * 功能:手指在屏幕上滑动时调用
     * @param event
     */
    private void touchMove(MotionEvent event){
    	//二次贝塞尔,实现平滑曲线;clickX, clickY为操作点,(clickX+startX)/2, (clickY+startY)/2为终点 
    	path.quadTo(clickX, clickY, (clickX+startX)/2, (clickY+startY)/2);
    	//第二次执行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值 
    	clickX = startX;
    	clickY = startY;
        invalidate();
    }
    
    /**
     * 功能:手指离开屏幕时调用
     * @param event
     */
    private void touchUp(MotionEvent event){
    	//鼠标弹起保存最后状态  
    	canvas.drawPath(path, paint);
    	//重置绘制路线,即隐藏之前绘制的轨迹  
		path.reset();
    }
这样画布和画笔我们都创建就好了,除了上面的两个方法,我们一般还会用到onDetachedFromWindow(),这个方法是在view退出时调用的,我们在这里可以释放一些操作。好了,自定的一个view控件就结束,接下来我们是调用这个view,就像实现系统控件一样,在布局文件中设置:

<com.xinhui.view.HandWritingView
            android:id="@+id/handwriteview"
            android:layout_width="fill_parent"
            android:layout_height="350dp"
            android:layout_above="@+id/pageNumber"
            android:layout_alignParentLeft="true" />

接下来在activity中的调用就和系统控件的调用一样了。
这样就可以在上面自由的书写了,而且很流畅、很平滑。由于今天的代码比较简单,就不上传资源了,明天我们会继续介绍有关手写画板的另一个比较复杂些的功能-画笔风格设置。欢迎大家继续关注,有什么不足之处,请指正,欢迎一起讨论……




### 回答1: 关系代数是一种用于描述和操作关系数据库中数据的数学形式的语言。关系代数中的操作包括并、差、投影、选择等。下面是我用300字中文回答的关系代数题,题目是手写CSDN。 假设我们有一个关系表格CSDN,其中包含了网站用户的信息。表格中的列有:姓名(name)、邮箱(email)、密码(password)、博客数量(blogNum)、关注数量(followNum)。我们的目标是根据给定的条件筛选出满足要求的用户。 首先,我们要筛选出姓名包含"csdn"的用户。这可以通过选择操作来实现。 CSDN = 选择(姓名包含"csdn")(CSDN) 接下来,我们想要找出博客数量大于100且关注数量大于50的用户。这可以通过选择操作和投影操作来实现。 CSDN = 选择(博客数量 > 100 and 关注数量 > 50)(CSDN) CSDN = 投影(姓名, 邮箱, 密码)(CSDN) 最后,我们要对结果按照姓名的字母顺序进行排序。这可以通过排序操作来实现。 CSDN = 排序(姓名升序)(CSDN) 通过以上操作,我们就可以得到满足条件的用户列表,并按照姓名的字母顺序进行排序。这是手写CSDN的关系代数解答。关系代数可以帮助我们对关系数据库进行高效的查询和操作。 ### 回答2: 关系代数是一种用于描述和操作关系型数据库的数学工具。在关系代数中,最基本的操作包括选择(select)、投影(project)、联接(join)和并(union)等。 选择操作根据给定的条件来从关系中选择满足条件的元组。例如,假设有一个关系R,包含属性A、B和C,我们可以使用选择操作从R中选择满足条件A=1的元组。 投影操作用于从给定的关系中选择出所需的属性。例如,假设有一个关系R,包含属性A、B和C,我们可以使用投影操作选择出属性A和B,即只保留关系中的属性A和B。 联接操作用于将两个关系的元组进行组合。例如,假设有两个关系R和S,它们都包含属性A和B,我们可以使用联接操作将两个关系中属性A和B相等的元组进行组合。 并操作用于将两个关系的元组进行合并。例如,假设有两个关系R和S,它们具有相同的属性,我们可以使用并操作将两个关系中的元组合并成一个新的关系。 通过组合使用上述基本操作,我们可以进行复杂的关系查询。例如,我们可以先进行选择操作,然后再进行投影操作,以此来获取我们所需的结果。 总之,关系代数提供了一种形式化的方法来描述和操作关系型数据库,它具有清晰的理论基础和严格的数学定义,能够帮助我们进行高效和准确的数据库操作。 ### 回答3: 关系代数是一种描述和操作关系数据库的形式化语言。根据题目中的要求,我们可以通过关系代数的运算来手写csdn。 假设题目所给的关系R表示CSDN,其中包含的属性有:用户名(username)、注册时间(registration_date)、粉丝数(fans_count)以及博文数(blog_count)。 首先,我们可以从R中选择出注册时间大于2019年的用户,表示为R1 = σ(注册时间 > 2019年)(R)。接着,我们可以对R1进行投影操作,选择出用户名、粉丝数和博文数这个属性,表示为R2 = π(用户名, 粉丝数, 博文数)(R1)。 然后,我们可以从R2中选择出粉丝数大于1000的用户,表示为R3 = σ(粉丝数 > 1000)(R2)。接着,我们可以对R3进行排序操作,按照博文数降序排列,表示为R4 = ρ(博文数)(R3)。 最后,我们可以选择R4中的前10个元组,表示为R5 = τ10(R4)。最终得到的关系R5即为满足题目要求的结果,它包含了用户名、粉丝数和博文数这个属性,并按照博文数降序排列,显示前10个元组。 通过以上关系代数的运算,我们可以手写出满足题目要求的CSDN关系。当然,实际运算过程中可能涉及更多的操作符和条件,这里仅仅提供了一个简单的示例。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值