閱讀801 返回首頁    go 人物


保存手寫簽名

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="https://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="https://schemas.android.com/apk/res/android"
    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文件。

最後更新:2017-04-03 20:19:15

  上一篇:go maven私服nexus-bundle的安裝和啟動
  下一篇:go Linux網絡設置3——ssh工具使用的注意點