安卓手写板app

来源:互联网 发布:c语言算法的基本特征 编辑:程序博客网 时间:2024/04/30 20:30

最近做的一个课程实验,开发一个可以手写的应用程序,可供用户选择笔迹颜色以及笔迹大小。具体效果如下:


1)在XML文件中定义RadioGroup、RadioButton,SeekBar以及自定义View——WritingView。具体布局就不介绍了,后面直接给出代码。

2)在自定义View中实现手写功能:首先由于View中的onDraw方法每次绘制时都会把非当前轨迹清除,所以需要另外定义一个画布进行保存。这里定义Canvas和Bitmap。具体实现如下:

private Canvas mCanvas;     //定义画布private Bitmap mBitmap;
public WritingView(Context context, AttributeSet attrs) {    super(context, attrs);    mCanvas = new Canvas();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {    super.onSizeChanged(w, h, oldw, oldh);    mBitmap = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);    mCanvas.setBitmap(mBitmap);}
@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    canvas.drawBitmap(mBitmap,0,0,null);}
然后重写onTouchEvent方法,实现当手指在屏幕上移动时,会把手指移动轨迹画出来。
private float startX;       //手写起点private float startY;
public boolean onTouchEvent(MotionEvent event) {    switch (event.getAction()){        case MotionEvent.ACTION_DOWN:            startX = event.getX();//将手接触屏幕时的位置设为起点            startY = event.getY();            break;        case MotionEvent.ACTION_MOVE:            mCanvas.drawLine(startX,startY,                    event.getX(),event.getY(),paint);//画起点到移动点间的线            postInvalidate();//视图刷新            startX = event.getX();//重改起点,这样才能绘制出随着手移动的曲线来            startY = event.getY();            break;        case MotionEvent.ACTION_UP:            mCanvas.drawLine(startX,startY,event.getX(),event.getY(),paint);            postInvalidate();            break;        default:break;    }    return true;}
其中在移动过程中,画线结束后要改变起点位置,这样才能得到由一段段线段组成的曲线。
3)在自定义View中定义setColor和setPaintSize方法,用于在MainActivity中调用。
这样就完成了手写板的功能。下面给出MainActivity和WritingView的完整代码:
WritingView代码:
public class WritingView extends View {    Paint paint = new Paint();  //定义画笔    private Canvas mCanvas;     //定义画布    private Bitmap mBitmap;    private float startX;       //手写起点    private float startY;    public WritingView(Context context, AttributeSet attrs) {        super(context, attrs);        mCanvas = new Canvas();    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mBitmap = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);        mCanvas.setBitmap(mBitmap);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                startX = event.getX();//将手接触屏幕时的位置设为起点                startY = event.getY();                break;            case MotionEvent.ACTION_MOVE:                mCanvas.drawLine(startX,startY,                        event.getX(),event.getY(),paint);//画起点到移动点间的线                postInvalidate();//视图刷新                startX = event.getX();//重改起点,这样才能绘制出随着手移动的曲线来                startY = event.getY();                break;            case MotionEvent.ACTION_UP:                mCanvas.drawLine(startX,startY,event.getX(),event.getY(),paint);                postInvalidate();                break;            default:break;        }        return true;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawBitmap(mBitmap,0,0,null);    }    //改变画笔颜色的方法    public void setColor(int color){        if (paint!=null){            paint.setColor(color);        }    }    //改变画笔大小的方法    public void setPaintSize(float size){        if (paint!=null){            paint.setStrokeWidth(size);        }    }}
MainActivity代码:
import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.RadioGroup;import android.widget.SeekBar;public class MainActivity extends AppCompatActivity {    WritingView writingView;    private RadioGroup radioGroup;    private SeekBar seekBar;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        writingView = (WritingView) findViewById(R.id.writing);        radioGroup = (RadioGroup) findViewById(R.id.color_group);        seekBar = (SeekBar) findViewById(R.id.paint_size);        writingView.setColor(getResources().getColor(R.color.colorBlue));//设置默认情况下字体颜色为蓝色        writingView.setPaintSize(20);//设置默认情况下字体大小为20        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {            @Override            public void onCheckedChanged(RadioGroup group, int checkedId) {                //根据选择不同的radioButton项,调用writingView中的setColor方法改变画笔颜色                switch (checkedId){                    case R.id.black:                        writingView.setColor(getResources().getColor(R.color.colorBlack));                        break;                    case R.id.red:                        writingView.setColor(getResources().getColor(R.color.colorRed));                        break;                    case R.id.green:                        writingView.setColor(getResources().getColor(R.color.colorGreen));                        break;                    case R.id.blue:                        writingView.setColor(getResources().getColor(R.color.colorBlue));                        break;                    default:break;                }            }        });        final int seekBarMax = seekBar.getMax();//获取用于改变画笔大小的seekBar的最大值,目的是便于将seekBar值转换成百分数        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {            @Override            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                writingView.setPaintSize((float)progress*20/seekBarMax);//将seekBar的进度值转换成百分数并乘以倍数,实现改变画笔大小            }            @Override            public void onStartTrackingTouch(SeekBar seekBar) {            }            @Override            public void onStopTrackingTouch(SeekBar seekBar) {            }        });    }}