android项目 之 记事本(4) ----- 添加画板

时间:2021-06-03 06:54:05

         画板功能在很多应用上都有,用户可以在画板上自己绘图,其基本的功能有,通过画笔绘图,调整画笔大小,修改画笔颜色,橡皮擦功能,撤销与恢复,清除屏幕等。

         先上图:

android项目 之 记事本(4) ----- 添加画板       android项目 之 记事本(4) ----- 添加画板

           基本的功能也上图中可以体现出来。

           首先给出画板的布局文件,

          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等比例缩小,并添加在记事中,这些代码和之前的添加照片功能的代码一样,复用就可以。

       这样添加画板并将所绘制的图形添加在记事本当中,就已完成,至于画板的多种功能,以后慢慢完善。