画板功能在很多应用上都有,用户可以在画板上自己绘图,其基本的功能有,通过画笔绘图,调整画笔大小,修改画笔颜色,橡皮擦功能,撤销与恢复,清除屏幕等。
先上图:
基本的功能也上图中可以体现出来。
首先给出画板的布局文件,
activity_paint.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/paint_layout"
>
<GridView
android:id="@+id/paintBottomMenu"
android:layout_width="match_parent"
android:layout_height="45dp"
android:numColumns="auto_fit"
android:background="@drawable/navigationbar_bg"
android:horizontalSpacing="10dp"
android:layout_alignParentBottom="true"
></GridView>
</RelativeLayout>
里面的GridView是画板底部选项的容器。画板界面在代码里定义。
主要步骤为:
1) GridView添加适配器,将选项菜单装载到GridView中。
2) 将绘制的图形以图片格式保存在指定的SD卡文件夹下。
3) 给顶部保存按钮添加监听器,保存绘图并返回图片路径,显示在EditText中。
整个Activity代码如下:
PaintActivity.java
package com.example.notes;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class PaintActivity extends Activity {
private Paint mPaint;
private RelativeLayout paintLayout;
private GridView paint_bottomMenu;
private ListView lv_popWindow;
//菜单资源
private int[] paintItems = {
R.drawable.paint_pencil,
R.drawable.paint_icon_color,
R.drawable.paint_icon_back,
R.drawable.paint_icon_forward,
R.drawable.paint_icon_delete
};
private Button btn_save;
private Button btn_back;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private PopupWindow popupWindow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(new TouchView(this));
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_paint);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_add);
//将自定义标题栏的标题定义为绘图
TextView title = (TextView)findViewById(R.id.tv_title);
title.setText("绘图");
paint_bottomMenu = (GridView)findViewById(R.id.paintBottomMenu);
paintLayout = (RelativeLayout)findViewById(R.id.paint_layout);
paintLayout.addView(new TouchView(this));
InitPaintMenu();
btn_save = (Button)findViewById(R.id.bt_save);
btn_back = (Button)findViewById(R.id.bt_back);
btn_save.setOnClickListener(new ClickEvent());
btn_back.setOnClickListener(new ClickEvent());
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF00FF00);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(10);
}
//配置绘图菜单
public void InitPaintMenu(){
ArrayList<Map<String,Object>> menus = new ArrayList<Map<String,Object>>();
for(int i = 0;i < paintItems.length;i++){
Map<String,Object> item = new HashMap<String,Object>();
item.put("image",paintItems[i]);
menus.add(item);
}
paint_bottomMenu.setNumColumns(paintItems.length);
paint_bottomMenu.setSelector(R.drawable.bottom_item);
SimpleAdapter mAdapter = new SimpleAdapter(PaintActivity.this, menus,R.layout.item_button, new String[]{"image"}, new int[]{R.id.item_image});
paint_bottomMenu.setAdapter(mAdapter);
}
class ClickEvent implements OnClickListener{
@Override
public void onClick(View v) {
if(v == btn_save){
//得到调用该Activity的Intent对象
Intent intent = getIntent();
Bundle b = new Bundle();
String path = saveBitmap(mBitmap);
b.putString("paintPath", path);
intent.putExtras(b);
setResult(RESULT_OK, intent);
PaintActivity.this.finish();
}
else if(v == btn_back){
PaintActivity.this.finish();
}
}
}
//设置菜单项监听器
class MenuClickEvent implements OnItemClickListener{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent intent;
switch(position){
//画笔大小
case 0:
break;
//颜色
case 1:
break;
//撤销
case 2:
break;
//恢复
case 3:
break;
//删除
case 4 :
break;
default :
break;
}
}
}
//保存绘图文件
public String saveBitmap(Bitmap bitmap){
//获得系统当前时间,并以该时间作为文件名
SimpleDateFormat formatter = new SimpleDateFormat ("yyyyMMddHHmmss");
Date curDate = new Date(System.currentTimeMillis());//获取当前时间
String str = formatter.format(curDate);
String paintPath = "";
str = str + "paint.png";
File dir = new File("/sdcard/notes/");
File file = new File("/sdcard/notes/",str);
if (!dir.exists()) {
dir.mkdir();
}
else{
if(file.exists()){
file.delete();
}
}
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
//保存绘图文件路径
paintPath = "/sdcard/notes/" + str;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return paintPath;
}
//自定义View public class TouchView extends View { public TouchView(Context c) { super(c); //画布大小 mBitmap = Bitmap.createBitmap(480, 690, Bitmap.Config.RGB_565); mCanvas = new Canvas(mBitmap); //所有mCanvas画的东西都被保存在了mBitmap中 mCanvas.drawColor(Color.WHITE); mPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); //显示旧的画布 canvas.drawPath(mPath, mPaint); //画最后的path } private float mX, mY; private static final float TOUCH_TOLERANCE = 4; private void touch_start(float x, float y) { mPath.reset();//清空path 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, y);// mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);//源代码是这样写的,可是我没有弄明白,为什么要这样? mX = x; mY = y; } } private void touch_up() { mPath.lineTo(mX, mY); mCanvas.drawPath(mPath, mPaint); mPath.reset(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); //清屏 break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } } }
画板的调整画笔大小等功能还没实现,这个以后慢慢添加,先将整个框架搭起来。调用该Activity的方法依然是startActivityForResult方法,因此需要在上一个Activity的onActivityResult添加代码,具体如下:
1)在画板图标的点击监听器中添加如下代码,这里将requestCode 设为3,为了和拍照和选择照片功能区分开
intent = new Intent(AddActivity.this,PaintActivity.class);
startActivityForResult(intent, 3);
2)在绘图Activity中将所绘制的图形以图片格式保存,并将路径返回给添加记事Activity中,主要代码为:
//得到调用该Activity的Intent对象
Intent intent = getIntent();
Bundle b = new Bundle();
String path = saveBitmap(mBitmap);
b.putString("paintPath", path);
intent.putExtras(b);
setResult(RESULT_OK, intent);
PaintActivity.this.finish();
其实这几行代码就在上面的 PaintActivity.java里
3)在AddActivity.java,也就是添加记事Activity里的onActivityResult方法里取出返回的绘图文件路径,并将其装载在Bitmap中,以显示在EditText中。主要代码为:
//返回的是绘图后的结果
else if(requestCode == 3){
extras = data.getExtras();
String path = extras.getString("paintPath");
//通过路径取出图片,放入bitmap中
bitmap = BitmapFactory.decodeFile(path);
}
至于将取出的图片bitmap等比例缩小,并添加在记事中,这些代码和之前的添加照片功能的代码一样,复用就可以。
这样添加画板并将所绘制的图形添加在记事本当中,就已完成,至于画板的多种功能,以后慢慢完善。