专栏首页向治洪保存手写签名

保存手写签名

Android 提供了很多丰富、实用而且很有特色的功能。比如,语音识别、手写签名等等。本篇就为你介绍如何在android上进行个性化的手写签名。

首先大致说说需求:这是一个追求时尚、张扬个性的时代,我们希望在签名的地方,签名的是自己手写出来的很有个性的艺术字,而非根据手势识别出来的标准字体。

设计思路如下,在画板上进行签名(其实就是绘制图片),完成后保存为图片。然后将图片按照一定的比率进行缩放并显示在指定的位置。

这里给出一个实例,实例只是一个简单的例子,如有需要可以进行必要的扩展。这里我们需要一个Listener、一个Dialog、一个Activity这个三个java类。两个layout XML文件。

Listener很简单,主要是对手写板对话框的一个监听。

1 2 3 4 5

public interface DialogListener {            public void refreshActivity(Object object);    }

接着是画板的Dialog

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203

package cn.handwriting;    import android.app.Dialog; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager.LayoutParams; import android.widget.Button; import android.widget.FrameLayout;       public class WritePadDialog extends Dialog {        Context context;     LayoutParams p ;     DialogListener dialogListener;        public WritePadDialog(Context context,DialogListener dialogListener) {         super(context);         this.context = context;         this.dialogListener = dialogListener;     }        static final int BACKGROUND_COLOR = Color.WHITE;        static final int BRUSH_COLOR = Color.BLACK;        PaintView mView;        /** The index of the current color to use. */     int mColorIndex;        @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         requestWindowFeature(Window.FEATURE_NO_TITLE);         requestWindowFeature(Window.FEATURE_PROGRESS);         setContentView(R.layout.write_pad);                    p = getWindow().getAttributes();  //获取对话框当前的参数值           p.height = 320;//(int) (d.getHeight() * 0.4);   //高度设置为屏幕的0.4         p.width = 480;//(int) (d.getWidth() * 0.6);    //宽度设置为屏幕的0.6                   getWindow().setAttributes(p);     //设置生效                               mView = new PaintView(context);         FrameLayout frameLayout = (FrameLayout) findViewById(R.id.tablet_view);         frameLayout.addView(mView);         mView.requestFocus();         Button btnClear = (Button) findViewById(R.id.tablet_clear);         btnClear.setOnClickListener(new View.OnClickListener() {                @Override             public void onClick(View v) {                  mView.clear();             }         });            Button btnOk = (Button) findViewById(R.id.tablet_ok);         btnOk.setOnClickListener(new View.OnClickListener() {                @Override             public void onClick(View v) {                 try {                     dialogListener.refreshActivity(mView.getCachebBitmap());                     WritePadDialog.this.dismiss();                 } catch (Exception e) {                     e.printStackTrace();                 }             }         });                    Button btnCancel = (Button)findViewById(R.id.tablet_cancel);         btnCancel.setOnClickListener(new View.OnClickListener() {                            @Override             public void onClick(View v) {                 cancel();             }         });     }               /**      * This view implements the drawing canvas.      *      * It handles all of the input events and drawing functions.      */     class PaintView extends View {         private Paint paint;         private Canvas cacheCanvas;         private Bitmap cachebBitmap;         private Path path;            public Bitmap getCachebBitmap() {             return cachebBitmap;         }            public PaintView(Context context) {             super(context);                             init();                 }            private void init(){             paint = new Paint();             paint.setAntiAlias(true);             paint.setStrokeWidth(3);             paint.setStyle(Paint.Style.STROKE);             paint.setColor(Color.BLACK);                                path = new Path();             cachebBitmap = Bitmap.createBitmap(p.width, (int)(p.height*0.8), Config.ARGB_8888);                     cacheCanvas = new Canvas(cachebBitmap);             cacheCanvas.drawColor(Color.WHITE);         }         public void clear() {             if (cacheCanvas != null) {                                    paint.setColor(BACKGROUND_COLOR);                 cacheCanvas.drawPaint(paint);                 paint.setColor(Color.BLACK);                 cacheCanvas.drawColor(Color.WHITE);                 invalidate();                       }         }                                  @Override         protected void onDraw(Canvas canvas) {             // canvas.drawColor(BRUSH_COLOR);             canvas.drawBitmap(cachebBitmap, 0, 0, null);             canvas.drawPath(path, paint);         }            @Override         protected void onSizeChanged(int w, int h, int oldw, int oldh) {                            int curW = cachebBitmap != null ? cachebBitmap.getWidth() : 0;             int curH = cachebBitmap != null ? cachebBitmap.getHeight() : 0;             if (curW >= w && curH >= h) {                 return;             }                if (curW < w)                 curW = w;             if (curH < h)                 curH = h;                Bitmap newBitmap = Bitmap.createBitmap(curW, curH, Bitmap.Config.ARGB_8888);             Canvas newCanvas = new Canvas();             newCanvas.setBitmap(newBitmap);             if (cachebBitmap != null) {                 newCanvas.drawBitmap(cachebBitmap, 0, 0, null);             }             cachebBitmap = newBitmap;             cacheCanvas = newCanvas;         }            private float cur_x, cur_y;            @Override         public boolean onTouchEvent(MotionEvent event) {                            float x = event.getX();             float y = event.getY();                switch (event.getAction()) {             case MotionEvent.ACTION_DOWN: {                 cur_x = x;                 cur_y = y;                 path.moveTo(cur_x, cur_y);                 break;             }                case MotionEvent.ACTION_MOVE: {                 path.quadTo(cur_x, cur_y, x, y);                 cur_x = x;                 cur_y = y;                 break;             }                case MotionEvent.ACTION_UP: {                 cacheCanvas.drawPath(path, paint);                 path.reset();                 break;             }             }                invalidate();                return true;         }     }    }

Activity是程序的入口,这个必不可少。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

package cn.handwriting;    import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import android.app.Activity; import android.graphics.Bitmap; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.TextView;    public class HandwritingActivity extends Activity {     /** Called when the activity is first created. */            private Bitmap mSignBitmap;     private String signPath;     private ImageView ivSign;     private TextView tvSign;     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.main);         setTitle("欢迎使用手写签名");         ivSign =(ImageView)findViewById(R.id.iv_sign);         tvSign = (TextView)findViewById(R.id.tv_sign);                         ivSign.setOnClickListener(signListener);         tvSign.setOnClickListener(signListener);     }                   private OnClickListener signListener = new View.OnClickListener() {                    @Override         public void onClick(View v) {             WritePadDialog writeTabletDialog = new WritePadDialog(                     HandwritingActivity.this, new DialogListener() {                         @Override                         public void refreshActivity(Object object) {                                                                                       mSignBitmap = (Bitmap) object;                             signPath = createFile();                             /*BitmapFactory.Options options = new BitmapFactory.Options();                             options.inSampleSize = 15;                             options.inTempStorage = new byte[5 * 1024];                             Bitmap zoombm = BitmapFactory.decodeFile(signPath, options);*/                                                                                  ivSign.setImageBitmap(mSignBitmap);                             tvSign.setVisibility(View.GONE);                         }                     });             writeTabletDialog.show();         }     };            /**      * 创建手写签名文件      *      * @return      */     private String createFile() {         ByteArrayOutputStream baos = null;         String _path = null;         try {             String sign_dir = Environment.getExternalStorageDirectory() + File.separator;                       _path = sign_dir + System.currentTimeMillis() + ".jpg";             baos = new ByteArrayOutputStream();             mSignBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);             byte[] photoBytes = baos.toByteArray();             if (photoBytes != null) {                 new FileOutputStream(new File(_path)).write(photoBytes);             }            } catch (IOException e) {             e.printStackTrace();         } finally {             try {                 if (baos != null)                     baos.close();             } catch (IOException e) {                 e.printStackTrace();             }         }         return _path;     } }

对应的两个layout文件

main.xml

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="fill_parent"     android:layout_height="fill_parent"     android:orientation="vertical" >        <ImageView          android:id="@+id/iv_sign"          android:layout_marginTop="50dp"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_gravity="center"          />             <TextView         android:id="@+id/tv_sign"         android:layout_marginTop="50dp"         android:layout_below="@id/iv_sign"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:text="点此签名"         />      </LinearLayout>

write_pad.xml

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:greendroid="http://schemas.android.com/apk/res/com.cyrilmottier.android.gdcatalog"     android:layout_width="fill_parent"     android:layout_height="fill_parent"     android:orientation="vertical" >        <FrameLayout         android:id="@+id/tablet_view"         android:layout_width="fill_parent"         android:layout_height="0dp"         android:layout_weight="1"         android:background="@color/white">     </FrameLayout>        <LinearLayout         android:layout_width="fill_parent"         android:layout_height="wrap_content"         android:background="@android:drawable/bottom_bar"         android:paddingTop="4dp" >            <Button             android:id="@+id/tablet_ok"             android:layout_width="0dp"             android:layout_height="wrap_content"             android:layout_weight="1"             android:text="确定" />                    <Button             android:id="@+id/tablet_clear"             android:layout_width="0dp"             android:layout_height="wrap_content"             android:layout_weight="1"             android:text="清除" />            <Button             android:id="@+id/tablet_cancel"             android:layout_width="0dp"             android:layout_height="wrap_content"             android:layout_weight="1"             android:text="取消" />     </LinearLayout>    </LinearLayout>

这里还有个样式的设置,所以在values下添加了一个colors.xml文件。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • android推荐使用dialogFrament而不是alertDialog

    DialogFragment在android 3.0时被引入。是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框。典型的用于:展...

    xiangzhihong
  • android自定义密码键盘

    先上图 ? 先看一下键盘的布局文件control_digitpasswordkeypad.xml <?xml version="1.0" encoding="u...

    xiangzhihong
  • DrawerLayout实现网易新闻抽屉效果

    个人感觉网易的客户端比较前卫,有很多新鲜的东西,有时候模仿这些好的客户端能学到很多东西 开始今天的主要课题,下面是网易客户端抽屉模式实现的效果 ? ? 其...

    xiangzhihong
  • Android实现类似execel的表格 能回显并能修改表格内容的方法

    以上这篇Android实现类似execel的表格 能回显并能修改表格内容的方法就是小编分享给大家的全部内容了,希望能给大家一个参考。

    砸漏
  • Android自定View流式布局根据文字数量换行

    本文实例为大家分享了Android根据文字数量换行的具体代码,供大家参考,具体内容如下

    砸漏
  • [android] post请求接口demo测试代码

    陶士涵
  • 安卓 —— 图灵机器人+讯飞语音设计实现

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

    泥豆芽儿 MT
  • Android 设备唯一标识(适配Android版本)

      相信在看这篇文章之前你已经看过一些类似的文章了,那么你肯定知道自己想要的是什么。

    晨曦_LLW
  • Android自定义文件路径选择器

    文中涉及到文件名称排序,固定根目录以及返回上一层在上面,方便选择等。根据文件后缀,筛选文件还没做。先看效果。

    砸漏
  • 8.Android-简单的登录案例编写

    本章来学习登录案例,由于还未学习自定义控件外观,所以ui界面先用最简单的,并保存登录账号密码到data/data/包名/files下

    张诺谦

扫码关注云+社区

领取腾讯云代金券