引自:http://www.xuebuyuan.com/1754358.html

既然我们实现了画布和画笔,也实现了手写,为了提高可用性,我们增加了对画笔风格的设置功能,这样就可以根据自己的需要选择画笔的颜色、粗细、风格(铅笔、浮雕、水彩等)效果。今天我们就介绍画笔风格的设置功能的实现过程,先看看效果图:

         
               

一、实现原理:

1、对话款我们用的是popupwindow,不是alertdialog对话框,两者是有区别的:前者是阻塞型,即popupwindow会阻塞主线程,当popupwindow弹出来后,主线程暂停工作,只有popupwindow退出后,主线程才会恢复;alertdialog是非阻塞型,即不会影响到主线程的工作。两者在实现过程中,都是将自定义的布局嵌入到其里面。对于popupwindow对话框的实现,之前的博客【android开发】手机应用管理器的实现之实现popupWindow类对话框(二)已经介绍了,这里就不在介绍了。
2、  为了更好地显示当前选择画笔的实际效果,我们做了动态预览,这是自定义两个view:ShowLineView和PenCircleView,来完成相应的操作。

3、由于今天要创建的文件比较多,我们来先看一下项目的目录结构图:

二、实现过程:

首先我们新建一个布局文件pen_set.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/setpenlayout"
android:layout_width="wrap_content"
android:layout_height="360dp"
android:orientation="horizontal"
android:background="@drawable/grey_layout">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:orientation="vertical"
android:paddingLeft="7dip">
<FrameLayout
android:layout_width="195dip"
android:layout_height="60dip"
android:background="@drawable/white_layout"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp" >
<LinearLayout
android:orientation="horizontal" android:paddingRight="12dip"
android:layout_width="195dip" android:id="@+id/penShowLayout"
android:layout_height="60dip" >
</LinearLayout>
</FrameLayout>
<LinearLayout android:id="@+id/sizeSelectLayoutPen"
android:layout_width="195dip" android:layout_height="40dip"
android:orientation="horizontal"
android:background="@drawable/darkgrey_layout"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:focusable="false" android:paddingRight="12dip">
<SeekBar
android:id="@+id/penSizeSeekBar"
android:layout_width="140dp"
android:layout_marginLeft="10dp"
android:max=""
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxHeight="5dp"
android:progressDrawable="@drawable/seekbar_bg_img"
/>
<LinearLayout
android:id="@+id/penSizeShowLayout"
android:layout_marginTop="10dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="6dp"
android:orientation="horizontal"></LinearLayout>
</LinearLayout> <LinearLayout
android:orientation="horizontal"
android:paddingRight="12dip"
android:layout_width="195dip"
android:id="@+id/pen_style_seclct"
android:layout_height="60dip"
android:background="@drawable/deepgrey_layout"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp">
<RadioGroup android:id="@+id/penRaidoGroup1"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal" android:layout_marginTop="8dip">
<RadioButton
android:id="@+id/buttonBlurPen" android:layout_weight=""
android:layout_width="0dip" android:button="@null"
android:layout_height="wrap_content"
android:background="@drawable/plainpen"
>
</RadioButton>
<RadioButton
android:id="@+id/buttonEmboss" android:layout_weight=""
android:layout_width="0dip" android:button="@null"
android:layout_height="wrap_content"
android:background="@drawable/embosspen">
</RadioButton>
<RadioButton
android:id="@+id/buttonPlainPen" android:layout_weight=""
android:layout_width="0dip" android:button="@null"
android:layout_height="wrap_content" android:background="@drawable/blurpen">
</RadioButton>
<RadioButton
android:id="@+id/buttonSelectBackGroundColor" android:layout_weight=""
android:layout_width="0dip" android:button="@null"
android:layout_height="wrap_content"
android:background="@drawable/fourpen">
</RadioButton>
</RadioGroup>
</LinearLayout> <LinearLayout android:layout_width="195dip"
android:background="@drawable/verygrey_layout"
android:layout_marginBottom="10dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_height="75dip" android:id="@+id/LinearLayoutColor"
android:paddingLeft="7dip" android:orientation="vertical"
android:paddingRight="10dip"> <LinearLayout android:layout_width="wrap_content" android:layout_height="28dip"
android:orientation="horizontal" android:layout_marginTop="7dip">
<RadioGroup android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/radioGroupColor"
android:orientation="horizontal" ></RadioGroup>
</LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="28dip"
android:orientation="horizontal" >
<RadioGroup android:layout_width="wrap_content"
android:layout_height="fill_parent" android:id="@+id/radioGroupColor2"
android:orientation="horizontal" ></RadioGroup>
</LinearLayout> </LinearLayout> </LinearLayout> <RelativeLayout
android:id="@+id/savedPenLayout"
android:layout_width="45dp"
android:layout_height="252dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:background="@drawable/verygrey_layout"
android:orientation="vertical" > </RelativeLayout> </LinearLayout>

在mudpdfactivity中先初始化控件:

/**
* 功能:初始化设置画笔popupwindow视图里面的控件
*/
public void initialSetPenBtV(){
penSetView = getLayoutInflater().inflate(R.layout.pen_set, null);
setpenlayout = (LinearLayout) penSetView.findViewById(R.id.setpenlayout) ;
penShowLayout = (LinearLayout) penSetView.findViewById(R.id.penShowLayout) ;
penSizeSeekBar = (SeekBar) penSetView.findViewById(R.id.penSizeSeekBar) ;
penSizeShowLayout = (LinearLayout) penSetView.findViewById(R.id.penSizeShowLayout) ;
colorRadioGroup = (RadioGroup) penSetView.findViewById(R.id.radioGroupColor);
colorRadioGroup2 = (RadioGroup) penSetView.findViewById(R.id.radioGroupColor2);
//plainpen = (RadioButton) penSetView.findViewById(R.id.buttonPlainPen);
penRadioGroupf = (RadioGroup) penSetView.findViewById(R.id.penRaidoGroup1);
penSizeSeekBar.setOnSeekBarChangeListener(this);
showLineView = new ShowLineView(this) ;
penShowLayout.addView(showLineView);
penCircleView = new PenCircleView(this) ;
penSizeShowLayout.addView(penCircleView,,);
showLineView.setAttr(, Color.BLACK, mPenType) ; initpenRadioGroupf(penSetView);
}

我们是在长按事件中弹出对话框:

@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
updateLineShow();
if(penSetPop == null){
penSetPop = new PopupWindow(penSetView,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
penSetPop.setBackgroundDrawable(getResources().getDrawable(R.drawable.popover_background_left));
penSetPop.setFocusable(true);
penSetPop.setOutsideTouchable(true);
penSetPop.showAsDropDown(mAddPicButton,,);
initColorViews();
}else{
penSetPop.setFocusable(true);
penSetPop.setOutsideTouchable(true);
penSetPop.showAsDropDown(mAddPicButton,,);
penSetPop.update();
}
return true;//返回false时,点击事件还会响应;返回true,长按事件后点击事件就不响应了
}

画笔的样式我们共做了四种样式,分别是铅笔、毛笔、签字笔、水彩笔,样式设置主要是通过类BlurMaskFilter和EmbossMaskFilte,通过改变他们的属性变量值来改变画笔书写效果,比如投影值、透明度等,将类BlurMaskFilter和EmbossMaskFilte的实例对象设置好后通过类Paint的方法:setMaskFilter()来传给画笔paint

/**
* 功能:设置画笔风格
* @param mPaintType
* @return
*/
private MaskFilter getMaskFilter(int mPaintType){
MaskFilter maskFilter = null;
switch (mPaintType) {
case PEN_TYPE.PLAIN_PEN://签字笔风格
maskFilter = null;
break;
case PEN_TYPE.BLUR://铅笔模糊风格
maskFilter = new BlurMaskFilter(, BlurMaskFilter.Blur.NORMAL);
break;
case PEN_TYPE.EMBOSS://毛笔浮雕风格
maskFilter = new EmbossMaskFilter(new float[] { , , }, 0.4f, , 3.5f);
break;
case PEN_TYPE.TS_PEN://透明水彩风格
maskFilter = null;
mPenPaint.setAlpha();
break;
default:
maskFilter = null;
break;
}
mPenPaint.setMaskFilter(maskFilter);
return maskFilter;
}

在对话框中我们四个画笔选项:

/**
* 功能:操作设置画笔风格
* @param view
*/
private void initpenRadioGroupf(View view) { plainpen = (RadioButton) view.findViewById(R.id.buttonPlainPen);
plainpen.setChecked(true);
penRadioGroupf
.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == -) {
return;
}
switch (checkedId) {
case R.id.buttonBlurPen:
setToolTyle(PEN_TYPE.BLUR);
break;
case R.id.buttonEmboss:
setToolTyle(PEN_TYPE.EMBOSS);
break;
case R.id.buttonPlainPen:
setToolTyle(PEN_TYPE.PLAIN_PEN);
break;
case R.id.buttonSelectBackGroundColor:
setToolTyle(PEN_TYPE.TS_PEN);
break;
default:
break;
}
updateLineShow();
}
});
} /**
* 功能:设置画笔的样式
* */
private void setToolTyle(int type) {
//mPaintView.setCurrentPainterType(type);
mPenType = type; }

同时我们设置了十种颜色的选项,通过RadioGroup控件来动态添加选项,每一组五种,分成两组:

/**
* 功能:显示颜色选择视图ColorRadioGroup
*/
private void initColorRadioGroup() {
mColorViewList = new ArrayList<ColorView>();
mColorViewList.add(colorView1);
mColorViewList.add(colorView2);
mColorViewList.add(colorView3);
mColorViewList.add(colorView4);
mColorViewList.add(colorView5);
RadioGroup.LayoutParams params = new RadioGroup.LayoutParams(
COLOR_VIEW_SIZE, COLOR_VIEW_SIZE);
params.setMargins(, , , ); for (ColorView colorView : mColorViewList) {
colorRadioGroup.addView(colorView, params);
colorView.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
for (ColorView colorView : mColorViewList) {
if (buttonView.equals(colorView)
&& buttonView.isChecked()) { colorRadioGroup2.clearCheck();
penColor = colorView.getColor();
updateLineShow();
}
}
}
});
}
} /**
* 功能:显示颜色选择视图ColorRadioGroup2
*/
private void initColorRadioGroup2() {
mColorViewList2 = new ArrayList<ColorView>();
mColorViewList2.add(colorView7);
mColorViewList2.add(colorView8);
//mColorViewList.add(colorView9);
mColorViewList2.add(colorView10);
mColorViewList2.add(colorView11);
//mColorViewList.add(colorView12);
mColorViewList2.add(colorView13);
RadioGroup.LayoutParams params = new RadioGroup.LayoutParams(
COLOR_VIEW_SIZE, COLOR_VIEW_SIZE);
params.setMargins(, , , ); for (ColorView colorView2 : mColorViewList2) {
colorRadioGroup2.addView(colorView2, params);
colorView2.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
for (ColorView colorView2 : mColorViewList2) {
if (buttonView.equals(colorView2)
&& buttonView.isChecked()) {
//set the first row unchecked
colorRadioGroup.clearCheck();
penColor = colorView2.getColor();
updateLineShow();
}
}
}
});
}
}选中后更新两个view: /**
* 功能:更新画笔线条的粗细
*/
private void updateLineShow(){
showLineView.setAttr(penSize, penColor, mPenType) ;
penCircleView.penAttrChange(penSize, penColor) ;
//ColorDrawable colorDrawable = new ColorDrawable(mPaintView.getPenColor()) ;
//pencolor.setBackgroundColor(mPaintView.getPenColor()) ;
}

进度条来设置画笔的粗细:

@Override
public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
// TODO Auto-generated method stub
penSize = progress;
updateLineShow();
}

这样设置对话框基本就完成了,我们设置好,要将相应的数值传递给画笔,我们是通过三个全局变量来保存画笔的颜色、粗细、风格的。

paint.setColor(MuPDFActivity.penColor); //设置画笔的颜色
paint.setStrokeWidth(MuPDFActivity.penSize);//设置画笔的粗细
getMaskFilter(MuPDFActivity.mPenType);

当然了我们在实现过程中远比这要复杂,我们创建了几个画笔的接口文件已经封装了几个工具类,我们就不详细说了,可以看看项目的源码。好了,到此今天我们的任务就算结束了,现在读取pdf和书写画板都实现了,剩下就是怎么在pdf上签名了,下一篇我们将继续介绍最关键的一部分-在pdf文件上添加签名。欢迎大家继续关注,由于今天的代码比较多,在文章的最后面我们会将今天的代码分享给大家,项目运行是正常的,如果你在运行中出现问题,请在博客下面留言,大家一起讨论……

源码下载:http://download.csdn.net/detail/lixinhuixin/6709451

android-------手写签名系统的设计与实现之实现画笔设置的更多相关文章

  1. Blazor组件自做二 : 使用JS隔离制作手写签名组件

    Blazor组件自做二 : 使用JS隔离制作手写签名组件 本文相关参考链接 JavaScript 模块中的 JavaScript 隔离 Viewer.js工程 Blazor组件自做一 : 使用JS隔离 ...

  2. canvas画布实现手写签名效果

    最近项目中涉及到移动端手写签名的功能需求,将实现代码记录于此,供小伙伴们参考指摘哦~ HTML代码: <!--手写区--> <div class="mSign_signMa ...

  3. 第三篇:基于K-近邻分类算法的手写识别系统

    前言 本文将继续讲解K-近邻算法的项目实例 - 手写识别系统. 该系统在获取用户的手写输入后,判断用户写的是什么. 为了突出核心,简化细节,本示例系统中的输入为32x32矩阵,分类结果也均为数字.但对 ...

  4. 机器学习实战一:kNN手写识别系统

    实战一:kNN手写识别系统 本文将一步步地构造使用K-近邻分类器的手写识别系统.由于能力有限,这里构造的系统只能识别0-9.需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:32像素*3 ...

  5. uni-app通过canvas实现手写签名

    分享一个uni-app实现手写签名的方法 具体代码如下: <template> <view > <view class="title">请在下面 ...

  6. Ionic5手写签名SignaturePad

    测试程序下载:https://hanzhe.lanzous.com/itt47kncw3a 初始化项目 1. 首先新建一个Ionic5的项目: ionic start test-1 blank 2. ...

  7. Android 手写Binder 教你理解android中的进程间通信

    关于Binder,我就不解释的太多了,网上一搜资料一堆,但是估计还是很多人理解的有困难.今天就教你如何从 app层面来理解好Binder. 其实就从我们普通app开发者的角度来看,仅仅对于androi ...

  8. 【Machine Learning in Action --2】K-近邻算法构造手写识别系统

    为了简单起见,这里构造的系统只能识别数字0到9,需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:宽高是32像素的黑白图像.尽管采用文本格式存储图像不能有效地利用内存空间,但是为了方便理 ...

  9. k-近邻算法-手写识别系统

    手写数字是32x32的黑白图像.为了能使用KNN分类器,我们需要把32x32的二进制图像转换为1x1024 1. 将图像转化为向量 from numpy import * # 导入科学计算包numpy ...

随机推荐

  1. asp脱离源代码管理

    当项目中出现“未能找到与此解决方案关联的源代码管理提供程序.项目将视为不受源代码管理” 解决方法:1.vs2013打开项目, 2.提示“您正在打开的解决方案已绑定到以下Team Foundation ...

  2. dialog弹出,点击back按键无法返回问题解决

    今天阅读队友代码,调试代码中,发现对话框弹出点击back按键无法返回问题解决. 代码如下: /** * 单个按钮没有标题的弹框 * * @param context * @param content内 ...

  3. javascript 如何正确使用getElementById,getElementsByName(), and getElementsByTagName()

    WEB标准下可以通过getElementById(), getElementsByName(), and getElementsByTagName()访问DOCUMENT中的任一个标签. (1)get ...

  4. 三层交换机配置说明(华为S5700设置三个网段互通)

    1.配置Switch # 创建VLAN <HUAWEI> system-view[HUAWEI] sysname Switch[Switch] vlan batch 10 20 30# 配 ...

  5. HTML之打开/另存为/打印/刷新/查看原文件等按钮的代码

    ■打开■ <input name=Button onClick=document.all.WebBrowser.ExecWB(1,1) type=button value=打开> < ...

  6. json 数组 对象 xml 之间转换(待补充)

    json 数组  xml 对象   之间转换(待补充) 1 把对象的类型或者数组转换成字符串类型(或者更确切的说是json类型的). 此处参考链接http://www.jb51.net/article ...

  7. HDU 4857 逃生(反向拓扑排序+优先队列)

    ( ̄▽ ̄)" //这题对序号输出有要求,较小的序号优先输出,所以用到优先队列 //优先队列是优先弹出值最大的,所以最后要反向输出结果,才是正确的output #include<iost ...

  8. raise()函数

    kill和raise函数用来发送信号, 区别在于: kill把信号发送给进程或进程组. kill(pid_t pid, int signo) raise把信号发送给进程自己,相当于 raise(ing ...

  9. Git从远程库克隆

    上次我们讲了先有本地库,后有远程库,如何关联远程库. 现在,假设我们从零开始开发,那么最好的方式就是先创建远程库,然后从远程库克隆. 首先,登录GitHub,创建一个新的仓库,gitskill 创建过 ...

  10. 解决mac下atom安装插件失败问题

    activate-power-mode的超炫编辑效果打动了我,花时间安装了atom,之后在package,install里面找到了这个插件,但是安装失败,如下图所示: gyp info it work ...