Android上的第三方开源DrawableView支持手写,类似于写字板。DrawableView支持改变画笔颜色,画笔线条粗细,画布的手势缩放和拖曳显示部分区域。并最终支持将手绘的图保存到本地。
在github上的项目主页:https://github.com/PaNaVTEC/DrawableView
先把布局文件中写一个DrawableView:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.zzw.testdrawableview.MainActivity" > <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" > <Button
android:id="@+id/subWidth"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="@drawable/sub" /> <Button
android:id="@+id/addWidth"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="@drawable/add" /> <Button
android:id="@+id/sava"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="@drawable/sava" /> <Button
android:id="@+id/PaintColor"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentTop="true"
android:layout_marginRight="50dp"
android:layout_toLeftOf="@+id/sava"
android:background="@drawable/rand" /> <Button
android:id="@+id/undo"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentTop="true"
android:layout_marginLeft="50dp"
android:layout_toRightOf="@+id/sava"
android:background="@drawable/ret" /> </RelativeLayout> <me.panavtec.drawableview.DrawableView
android:id="@+id/paintView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_weight="1" /> </LinearLayout>
JAVA代码:
package com.zzw.testdrawableview; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import me.panavtec.drawableview.DrawableView;
import me.panavtec.drawableview.DrawableViewConfig; public class MainActivity extends Activity implements OnClickListener { private DrawableView drawableView;
private DrawableViewConfig config; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); config = new DrawableViewConfig(); drawableView = (DrawableView) findViewById(R.id.paintView); Button addWidth = (Button) findViewById(R.id.addWidth);
Button subWidth = (Button) findViewById(R.id.subWidth);
Button PaintColor = (Button) findViewById(R.id.PaintColor);
Button undo = (Button) findViewById(R.id.undo);
Button sava = (Button) findViewById(R.id.sava); addWidth.setOnClickListener(this);
subWidth.setOnClickListener(this);
PaintColor.setOnClickListener(this);
undo.setOnClickListener(this);
sava.setOnClickListener(this); // 画笔颜色
config.setStrokeColor(Color.RED); // 画布边界
config.setShowCanvasBounds(true); // 设置画笔宽度
config.setStrokeWidth(10.0f); // 缩放
config.setMinZoom(1.0f);
config.setMaxZoom(3.0f); // 画布宽和高
config.setCanvasHeight(3000);
config.setCanvasWidth(2000); drawableView.setConfig(config);
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.addWidth:
// 设置每次增加10.0的宽度
config.setStrokeWidth(config.getStrokeWidth() + 10);
Toast.makeText(getApplicationContext(),
"当前画笔宽度:" + config.getStrokeWidth(), 0).show();
break; case R.id.subWidth:
// 设置每次减少10.0的宽度
if (config.getStrokeWidth() > 10) {
config.setStrokeWidth(config.getStrokeWidth() - 10);
Toast.makeText(getApplicationContext(),
"当前画笔宽度:" + config.getStrokeWidth(), 0).show();
}
break; case R.id.PaintColor:
// 测试期间,随机生成一种颜色
int r1 = (int) (Math.random() * 256);
int r2 = (int) (Math.random() * 256);
int r3 = (int) (Math.random() * 256);
config.setStrokeColor(Color.argb(255, r1, r2, r3));
Toast.makeText(getApplicationContext(), "颜色生成成功", 0).show();
break; case R.id.undo:
drawableView.undo();
break; case R.id.sava:
try {
savaBitmapToSDCard();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
} // 将用户手绘的DrawableView转化为图片保存到本地系统默认的图片库中。
private void savaBitmapToSDCard() throws IOException { // 从DrawableView获得Bitmap
Bitmap bmp = drawableView.obtainBitmap(); // 获取保存的路径
File parent_path = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File f = new File(parent_path.getAbsoluteFile(), "myDrawableView.png");
f.createNewFile();
Log.d("保存路径", f.getAbsolutePath()); FileOutputStream fos = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close(); Toast.makeText(getApplicationContext(),
"保存成功,保存路径" + f.getAbsolutePath(), 1).show();
} }
默认的,在未发布的debug阶段,DrawableView会在画布上添加一些log日志输出。如果不打算在画布中显示log,可以修改DrawableView的源代码去掉DrawableView默认的log日志。关键代码有两行,在CanvasDrawer的库文件源代码中:
initLogger(); ... canvasLogger.log(canvas, canvasRect, viewRect, scaleFactor);
将这两行注释掉即可,如图: