android-------手写签名系统的设计与实现之实现画笔设置

引自: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="30"
            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="1"
            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="1"
            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="1"
            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="1"
            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,40,40);
        showLineView.setAttr(6, 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,0,0);
            initColorViews();
        }else{
            penSetPop.setFocusable(true);
            penSetPop.setOutsideTouchable(true);
            penSetPop.showAsDropDown(mAddPicButton,0,0);
            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(8, BlurMaskFilter.Blur.NORMAL);
                break;
            case PEN_TYPE.EMBOSS://毛笔浮雕风格
                maskFilter = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f); 
                break;
            case PEN_TYPE.TS_PEN://透明水彩风格
                maskFilter = null;
                mPenPaint.setAlpha(50);
                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 == -1) {
                            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(1, 2, 6, 6);

        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(1, 2, 6, 6);

        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

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。