当前位置: 代码迷 >> Android >> Android 手记签名实例
  详细解决方案

Android 手记签名实例

热度:30   发布时间:2016-05-01 20:30:55.0
Android 手写签名实例

??这篇文章本来想在一个月前就发布的,最近一直忙于国家电网手持终端的应用开发,所以没抽出时间来写。周末到了,终于可以闲下来整理整理。话不多说,直奔主题。

?

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

?

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

?

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

?

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

?

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

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

?

?

接着是画板的Dialog

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是程序的入口,这个必不可少。

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

<?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

?

<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文件。具体参见样例。

?

1 楼 14564187 2012-05-07  
感谢楼主 贡献好资源
  相关解决方案