Android 之简易涂鸦板

没有废话,简单粗暴。

1.创建一个自定义 view

创建一个 DrawView,继承自 android.view.View 类。在这个类中,先定义所需的属性,再创建一个构造方法。

public class DrawView extends View {

    private int view_width = 0;//画板宽度
    private int view_height = 0;//画板高度
    private float preX;//起始点的 x 坐标
    private float preY;//起始点的 y 坐标
    private Path path;//路径
    public Paint paint = null;//画笔
    Bitmap cacheBitmap = null;//定义一个内存中的图片,该图片作为缓冲区
    Canvas cacheCanvas = null;//定义 cacheBitmap 上的 Canvas 对象


    /*构造方法*/
    public DrawView(Context context, AttributeSet set){
        super(context,set);

    }

    /*重写 onDraw 方法*/
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

}

2.修改 xml 文件

修改 activity_main.xml 文件,并将自定义的 DrawView 添加到布局管理器中。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.example.test.DrawView
        android:id="@+id/drawView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

3.DrawView 的构造方法

在 DrawView 的构造方法中,首先获取屏幕的宽度和高度,并创建一个与该 view 相同大小的缓存区,然后创建一个新的画面,并实例化一个路径,再讲内存中的位图绘制到 cacheCanvas 中,最后实例化一个画笔,并设置画笔的相关属性。

//获取屏幕宽度
        view_width = context.getResources().getDisplayMetrics().widthPixels;
        //获取屏幕高度
        view_height = context.getResources().getDisplayMetrics().heightPixels;

        cacheBitmap = Bitmap.createBitmap(view_width,view_height, Bitmap.Config.ARGB_8888);
        //创建一个新的画布
        cacheCanvas = new Canvas();
        path = new Path();
        //在 cacheCanvas 上绘制 cacheBitmap
        cacheCanvas.setBitmap(cacheBitmap);

        paint = new Paint(Paint.DITHER_FLAG);
        //设置默认的画笔颜色
        paint.setColor(Color.RED);

        //设置填充方式为描边
        paint.setStyle(Paint.Style.STROKE);
        //设置笔刷的图形样式
        paint.setStrokeJoin(Paint.Join.ROUND);
        //设置画笔转弯处的连接风格
        paint.setStrokeCap(Paint.Cap.ROUND);
        //设置默认的画笔的宽度
        paint.setStrokeWidth(1);
        //使用抗锯齿功能
        paint.setAntiAlias(true);
        //使用抖动效果
        paint.setDither(true);

4.重写 onDraw 方法

在 DrawView 的 onDraw 方法中,设置背景颜色,绘制 cacheBitmap,绘制路径以及保存当前的状态到栈中,并调用 restore()方法恢复所保存的状态。

//设置背景颜色
        canvas.drawColor(0xFFFFFFFF);
        //采用默认设置创建一个画笔
        Paint bmpPaint = new Paint();

        //绘制cacheBitmap
        canvas.drawBitmap(cacheBitmap,0,0,bmpPaint);
        //绘制路径
        canvas.drawPath(path,paint);
        //保存 canvas 状态
        canvas.save(Canvas.ALL_SAVE_FLAG);
        //恢复 canvas 之前的保存状态,防止保存后对 canvas 执行的操作最后续的绘制有影响
        canvas.restore();

5.重写 onTouchEvent 方法

在 DrawView 类中,重写onTouchEvent() 方法,为该视图添加触摸时间监听器,在该方法中,首先获取触摸时间发生的位置,然后应用 switch 对时间的不同状态添加响应代码,最后调用invalidate()方法更新视图。

@Override
    public boolean onTouchEvent(MotionEvent event) {

        //获取触摸时间发生的位置
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()){

            case MotionEvent.ACTION_DOWN:

                //将绘图的起始点移到(x,y)的坐标位置
                path.moveTo(x,y);
                preX = x;
                preY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                float dx = Math.abs(x-preX);
                float dy = Math.abs(y-preY);

                //判断是否在允许的范围内
                if (dx>=5 || dy >= 5){
                    path.quadTo(preX,preY,(x+preX)/2,(y+preY)/2);
                    preX = x;
                    preY = y;
                }
                break;
            case MotionEvent.ACTION_UP:
                //绘制路径
                cacheCanvas.drawPath(path,paint);
                path.reset();
                break;
        }
        invalidate();

        //返回 true,表示处理方法已经处理该事件
        return true;
    }

6.编写 clear() 方法

写一个 clear() 方法,用来实现橡皮擦功能。

 public void clear() {

        //设置图形重叠时的处理方式
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        //设置橡皮擦的宽度
        paint.setStrokeWidth(50);
    }

7.编写 save() 方法

写一个方法,用来保存当前的绘图。


public void save() {

        try {
            saveBitmap("myPicture");
        }catch (IOException e){
            e.printStackTrace();
        }
    }

private void saveBitmap(String filename) throws IOException {

        //创建文件对象
        File file = new File("/sdcard/pictures/"+filename+".png");
        //创建一个新文件
        file.createNewFile();
        //创建一个文件输出流对象
        FileOutputStream out = new FileOutputStream(file);
        //将绘图内容压缩成 PNG 格式输出到输出流对象中
        cacheBitmap.compress(Bitmap.CompressFormat.PNG,100,out);
        //将缓冲区的数据全部写出到输出流中
        out.flush();
        //关闭文件输出流对象
        out.close();
    }

8.设置权限

 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

9.创建 menu 资源文件

在 res 目录下,创建menu 文件夹,在 menu 文件夹下,创建 toolsmenu.xml 资源文件。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:title="@string/color">
        <menu >
            <!-- 定义一组单选菜单项 -->
            <group android:checkableBehavior="single" >
                <!-- 定义子菜单 -->
                <item android:id="@+id/red" android:title="@string/color_red"/>
                <item android:id="@+id/green" android:title="@string/color_green"/>
                <item android:id="@+id/blue" android:title="@string/color_blue"/>
            </group>
        </menu>
    </item>
    <item android:title="@string/width">
        <menu >
            <!-- 定义子菜单 -->
            <group>
                <item android:id="@+id/width_1" android:title="@string/width_1"/>
                <item android:id="@+id/width_2" android:title="@string/width_2"/>
                <item android:id="@+id/width_3" android:title="@string/width_3"/>
            </group>
        </menu>
    </item>
    <item android:id="@+id/clear" android:title="@string/clear"/>
    <item android:id="@+id/save" android:title="@string/save"/>
</menu>

10.添加选项菜单

<1>重写onCreateOptionsMenu方法

在 activity 文件中,重写onCreateOptionsMenu()方法,在该方法中,实例化一个MenuInflater对象,并解析菜单资源文件。

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = new MenuInflater(this);
        menuInflater.inflate(R.menu.toolsmenu,menu);
        return super.onCreateOptionsMenu(menu);
    }

<2>重写onOptionsItemSelected方法

重写onOptionsItemSelected() 方法,分别对各个菜单项被选择时做出相应的处理。

@Override
    public boolean onOptionsItemSelected(MenuItem item) {

        //获取自定义视图
        DrawView drawView = (DrawView)findViewById(R.id.drawView1);
        //取消擦除效果
        drawView.paint.setXfermode(null);
        //初始化画笔的宽度
        drawView.paint.setStrokeWidth(1);

        switch (item.getItemId()){

            //设置画笔的颜色为红色
            case R.id.red:
                drawView.paint.setColor(Color.RED);
                item.setChecked(true);
                break;
            //设置画笔的颜色为绿色
            case R.id.green:
                drawView.paint.setColor(Color.GREEN);
                item.setChecked(true);
                break;
            //设置画笔的颜色为蓝色
            case R.id.blue:
                drawView.paint.setColor(Color.BLUE);
                item.setChecked(true);
                break;
            //设置画笔的宽度为1
            case R.id.width_1:
                drawView.paint.setStrokeWidth(1);
                break;
            //设置画笔的宽度为5
            case R.id.width_2:
                drawView.paint.setStrokeWidth(5);
                break;
            //设置画笔的宽度为10
            case R.id.width_3:
                drawView.paint.setStrokeWidth(10);
                break;
            //擦除绘画
            case R.id.clear:
                drawView.clear();
                break;
            //保存绘画
            case R.id.save:
                drawView.save();
                break;
        }

        return true;
    }

运行,就会得到一个简易的涂鸦板,可以改变画笔颜色,画笔宽度,擦除,保存等。

真是越来越有意思了呢!

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个简易涂鸦板的 Java 代码示例: ```java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DoodleBoard extends JFrame implements MouseListener, MouseMotionListener { private int lastX; private int lastY; private Color currentColor; private JPanel canvas; public DoodleBoard() { super("Doodle Board"); setLayout(new BorderLayout()); currentColor = Color.BLACK; canvas = new JPanel(); canvas.setBackground(Color.WHITE); canvas.addMouseListener(this); canvas.addMouseMotionListener(this); add(canvas, BorderLayout.CENTER); JPanel colorPanel = new JPanel(); colorPanel.setLayout(new GridLayout(1, 0)); add(colorPanel, BorderLayout.SOUTH); JButton blackButton = new JButton("Black"); blackButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { currentColor = Color.BLACK; } }); colorPanel.add(blackButton); JButton redButton = new JButton("Red"); redButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { currentColor = Color.RED; } }); colorPanel.add(redButton); setSize(400, 400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public void mousePressed(MouseEvent e) { lastX = e.getX(); lastY = e.getY(); } public void mouseDragged(MouseEvent e) { Graphics g = canvas.getGraphics(); g.setColor(currentColor); g.drawLine(lastX, lastY, e.getX(), e.getY()); lastX = e.getX(); lastY = e.getY(); } public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseMoved(MouseEvent e) {} public static void main(String[] args) { new DoodleBoard(); } } ``` 此代码创建了一个带有涂鸦板功能的窗口,用户可以在窗口中使用鼠标进行绘画。用户可以通过点击底部的按钮来选择颜色。涂鸦板使用 `JPanel` 组件作为画布,并在组件上使用 `MouseListener` 和 `MouseMotionListener` 来处理鼠标事件。在鼠标拖动期间,程序使用 `Graphics` 对象的 `drawLine` 方法来绘制线条。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值