该小demo的功能:界面是一个TextView和ImageView。TextView文本内容为:签名;ImageView添加单机事件监听器:实现点击弹出一个对话框,然后在对话框中用手触摸签名,点击对话框的确定项后,签名会在ImageView上显示。之后签名会保存在本地手机上,在相册中也能查看该签名。
其中整个项目布局图:
下面是layout布局中的代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical"
android:padding="10dp"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="签名:"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="18sp" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#2888" />
</LinearLayout>
界面显示如下:
MainActivity中的代码如下:
package job.sava_qianming;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView ivQianMing;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setViews();//控件初始化
setListener();//设置监听
}
private void setListener() {
//设置单击事件监听器
ivQianMing.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//获取布局泵对象
LayoutInflater inflater = getLayoutInflater();
//用布局泵构建布局
final View layout = inflater.inflate(R.layout.dialog_layout,(ViewGroup) findViewById(R.id.dialog_qianming));
//创建对话框并显示
new AlertDialog.Builder( MainActivity.this)
.setTitle("我的签名")//设置标题
.setView(layout)//设置view
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
private Bitmap beifangwenzhe_bt;
@Override
public void onClick(DialogInterface dialog, int which) {
//创建MyView对象
MyView bt = (MyView) layout.findViewById(R.id.qianmingren);
beifangwenzhe_bt = bt.getBitmap();
//ImageView设置背景
ivQianMing.setBackgroundDrawable(new BitmapDrawable(beifangwenzhe_bt));
//保存图片
try {
saveBitmap(beifangwenzhe_bt);
} catch (IOException e) {
e.printStackTrace();
}
}
private void saveBitmap(Bitmap bmp) throws IOException {
Log.e("TAG", "保存图片");
//要保存文件的文件夹路径
String folder=Environment.getExternalStorageDirectory().getAbsolutePath()+"/good/savePic";
//创建文件夹
File file=new File(folder);
//不存在就创建文件夹
if(!file.exists()){
file.mkdirs();
}
//用文件夹名和文件名创建一个要保存的文件
File file2=new File(folder, "bmp.png");
if(!file2.exists()){
file2.createNewFile();
}
//BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(file2));
//创建文件输出流
FileOutputStream out=new FileOutputStream(file2);
//对bitmap进行压缩
bmp.compress(CompressFormat.PNG, 100, out);
//Flushes this stream.
out.flush();
//关闭输出流
out.close();
Log.e("TAG", "已经保存!");
//发广播通知手机相册更新显示
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Log.e("TAG", file2.getAbsolutePath());
Uri uri = Uri.fromFile(file2);
intent.setData(uri);
MainActivity.this.sendBroadcast(intent);
Log.e("TAG", "手机中图册更新显示");
}
})
.setNegativeButton("取消", null).show();
}
});
}
private void setViews() {
//获取ImageView
ivQianMing=(ImageView)findViewById(R.id.imageView1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
点击图片的时候弹出一个对话框,该对话框需要添加一个view,该view的layout布局代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog_qianming"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical"
android:padding="10dp" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#FF888855"
android:orientation="vertical" >
<job.sava_qianming.MyView
android:id="@+id/qianmingren"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#ffffff" />
</RelativeLayout>
</LinearLayout>
对话框view的根节点中引用的自定义View的代码如下(MyView):
package job.sava_qianming;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class MyView extends View{
//声明变量
private Paint mPaint = new Paint();
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private long mStartTime;
private long mEndTime;
private List<Bitmap> mBitmaps;
private boolean isStart = false;
private Handler mHandler;
private Context mContext;
//构造方法
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
//设置画笔颜色
mPaint.setColor(Color.rgb(254, 242, 58));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(7);
mContext = context;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
mBitmap = Bitmap.createBitmap(mBitmap.getWidth(),
mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
mCanvas.setBitmap(mBitmap);
invalidate();
}
};
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setPaint(Paint paint) {
this.mPaint = paint;
}
public void setBitmapMap(List<Bitmap> bitmaps) {
mBitmaps = bitmaps;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0x00000000);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
/*
* 屏幕触摸事件
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mEndTime = System.currentTimeMillis();
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
mEndTime = System.currentTimeMillis();
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
mEndTime = System.currentTimeMillis();
touch_up();
invalidate();
break;
}
return true;
}
public Bitmap getBitmap() {
int width = mBitmap.getWidth();
int height = mBitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float) 600 / width);
float scaleHeight = ((float) 800 / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(mBitmap, 0, 0, width, height,
matrix, true);
return newbmp;
}
}
现在代码就写完了。以下是demo的演示图:
弹出对话框后在上面进行签名操作:
点击确定后显示在ImageView上:
保存在本地手机上路径如下:
在相册中更新显示如下:
到此就完成了该demo的功能。希望大家看后觉得有用的“顶一个”!谢谢各位博友。