最近android课老师布置了一个课后作业,是实现android涂鸦板的功能,

然后自己写了一个简单的涂鸦板,可以实现选择颜色、尺寸、清屏的功能。

首先是效果图:

主要是使用Canvas和Paint来实现画图,并使用触屏事件处理来获取用户滑动的坐标。

首先,新建一个类HandWrite并继承View

实现画图的主要方法是onDraw()方法。

onDraw():绘图主函数,但是onDraw方法是个触发事件产生的调用,只能通过特定的方法触发事件以来调用onDraw。

触发onDraw函数的方法是:invalidate或者postInvalidate

直接上代码:

package com.example.icarus.ch6_2;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.Stack;

/**
 * Created by icarus on 3/31/2016.
 * 自定义组件实现view
 * view上绘制Canvas对象,onDrow函数中实现
 */
public class HandWrite extends View{//定义画笔
    private Paint paint;
    //存放原始图像
    private Bitmap originalBitmap=null;
    //存放从原始图形复制的图像
    private Bitmap new1_Bitmap=null;
    //存放处理后的图像
    private Bitmap new2_Bitmap=null;
    //画线的起始坐标
    private float startX=0,startY=0;
    //第二次画线起始坐标
    private float secondX=0,secondY=0;
    //画线的终点坐标
    private float clickX=0,clickY=0;
    //清屏按钮是否按下
    private boolean isClear=false;
    //设置是否画线的标志
    private boolean isMove=true;
    //是否按下
    private boolean isDown=false;
    //记录绘画历史的栈
    private Stack<Bitmap> bitmap_stack=new Stack<Bitmap>();
    //控制是否出栈的标志
    private boolean isPOP=false;

    /**
     * 实现默认构造函数
     * @param context
     * @param attrs
     */
    public HandWrite(Context context, AttributeSet attrs) {super(context, attrs);
        //从资源中获取原始图形,android不允许在代码里修改res文件,下面的代码会出错
        //originalBitmap= BitmapFactory.decodeResource(getResources(),R.drawable.capture);
        //需使用这种格式代替
        originalBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.capture).copy(Bitmap.Config.ARGB_8888,true);
        new1_Bitmap=Bitmap.createBitmap(originalBitmap);
        paint=new Paint();
    }/**
     * 清除涂鸦
     */
    public void clear(){isClear=true;
        new2_Bitmap=Bitmap.createBitmap(originalBitmap);
        invalidate();
    }/**
     * 撤销功能实现
     */
    public void doPOP(){isPOP=true;
        new2_Bitmap=bitmap_stack.pop();
        invalidate();
    }/**
     * 设置颜色
     * @param count_color
     */
    public void setColor(int count_color){switch (count_color){case 0:paint.setColor(Color.RED);//设置红色
                break;
            case 1:paint.setColor(Color.BLACK);//设置黑色
                break;
            case 2:paint.setColor(Color.GREEN);//设置绿色
                break;
            case 3:paint.setColor(Color.YELLOW);//设置黄色
                break;
        }}/**
     * 设置画笔宽度
     * @param count_stro
     */
    public void setStyle(int count_stro){paint.setStyle(Paint.Style.FILL);//设置样式
        switch (count_stro){case 0:paint.setStrokeWidth(3.0f);
                break;
            case 1:paint.setStrokeWidth(5.0f);
                break;
            case 2:paint.setStrokeWidth(7.0f);
                break;
            case 3:paint.setStrokeWidth(9.0f);
                break;
        }}/**
     * 绘图主函数
     * 但是onDrow是个触发事件产生的调用,只能通过特定的方法触发事件以来调用onDrow
     * 触发onDrow函数的方法是:invalidate或者postInvalidate
     * @param canvas
     */
    public void onDraw(Canvas canvas){super.onDraw(canvas);
        canvas.drawBitmap(HandWriting(new1_Bitmap),0,0,null);
    }/**
     * 利用画板和画笔记录绘制的图形
     * @return
     */
    public Bitmap HandWriting(Bitmap o_Bitmap){Canvas canvas=null;//定义画布
        if(isClear){canvas=new Canvas(new2_Bitmap);//画布为已经绘制好的图形
        }else{canvas=new Canvas(o_Bitmap);
        }//初始化画笔
        paint.setAntiAlias(true);
        //开始画线
        if(isMove){canvas.drawLine(startX,startY,clickX,clickY,paint);//画线
            //将历史绘图存入栈中
            bitmap_stack.push(o_Bitmap);

        }startX=clickX;
        startY=clickY;
        if (isClear){return new2_Bitmap;
        }return o_Bitmap;
    }/**
     * 首先执行该方法
     * 全局监听触摸屏事件
     * 对画线坐标进行更新
     * @param event
     * @return
     */
    public boolean onTouchEvent(MotionEvent event){clickX=event.getX();
        clickY=event.getY();
        if (event.getAction()==MotionEvent.ACTION_DOWN){isMove=false;
            isDown=true;
            invalidate();//调用onDrow方法
            return true;
        }else if (event.getAction()==MotionEvent.ACTION_MOVE){isDown=false;
            isMove=true;
            invalidate();//调用onDrow方法
            return true;
        }return super.onTouchEvent(event);
    }
}

界面设置如下:

配置文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.icarus.ch6_2.MainActivity"
    android:weightSum="1">
    <com.example.icarus.ch6_2.HandWrite
        android:id="@+id/handwriteview"
        android:layout_width="match_parent"
        android:layout_height="375dp" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical">

            <Button
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:id="@+id/btnClear"
                android:text="@string/btn_clear"/>

            <Button
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:id="@+id/btnPOP"
                android:text="@string/btn_pop"/>

        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="1">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:orientation="horizontal">
                <Button
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:id="@+id/btnColorRed"
                    android:background="#ff0000"/>
                <Button
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:id="@+id/btnColorBlank"
                    android:background="#000000"/>
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:orientation="horizontal">
                <Button
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:id="@+id/btnColorGreen"
                    android:background="#00ff00"/>
                <Button
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:id="@+id/btnColorYellow"
                    android:background="#ffff00"/>
            </LinearLayout>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="1">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:orientation="horizontal">
                <Button
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:id="@+id/btnWidth2"
                    android:text="@string/btnwidth2"/>
                <Button
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:id="@+id/btnWidth1"
                    android:text="@string/btnwidtn1"/>

            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:orientation="horizontal">
                <Button
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:id="@+id/btnWidth3"
                    android:text="@string/btnwidth3"/>
                <Button
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:id="@+id/btnWidth4"
                    android:text="@string/btnwidth4"/>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

MainActivity代码如下:

package com.example.icarus.ch6_2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {private HandWrite handWrite=null;
    private Button btnClear,btnPOP,btnColorRed,btnColorBlank,btnColorGreen,btnColorYellow,btnWidth1,btnWidth2,btnWidth3,btnWidth4;
    @Override
    protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //新建画图函数
        handWrite= (HandWrite) findViewById(R.id.handwriteview);
        //红色颜色设置
        if(findViewById(R.id.btnColorRed)!=null){btnColorRed= (Button) findViewById(R.id.btnColorRed);
            btnColorRed.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.setColor(0);
                }});
        }//黑色颜色设置
        if(findViewById(R.id.btnColorBlank)!=null){btnColorBlank= (Button) findViewById(R.id.btnColorBlank);
            btnColorBlank.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.setColor(1);
                }});
        }//绿色颜色设置
        if(findViewById(R.id.btnColorGreen)!=null){btnColorGreen= (Button) findViewById(R.id.btnColorGreen);
            btnColorGreen.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.setColor(2);
                }});
        }//黄色颜色设置
        if(findViewById(R.id.btnColorYellow)!=null){btnColorYellow= (Button) findViewById(R.id.btnColorYellow);
            btnColorYellow.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.setColor(3);
                }});
        }//画笔大小设置
        if(findViewById(R.id.btnWidth1)!=null){btnWidth1= (Button) findViewById(R.id.btnWidth1);
            btnWidth1.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.setStyle(0);
                }});
        }//画笔大小设置
        if(findViewById(R.id.btnWidth2)!=null){btnWidth2= (Button) findViewById(R.id.btnWidth2);
            btnWidth2.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.setStyle(1);
                }});
        }//画笔大小设置
        if(findViewById(R.id.btnWidth3)!=null){btnWidth3= (Button) findViewById(R.id.btnWidth3);
            btnWidth3.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.setStyle(2);
                }});
        }//画笔大小设置
        if(findViewById(R.id.btnWidth4)!=null){btnWidth4= (Button) findViewById(R.id.btnWidth4);
            btnWidth4.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.setStyle(3);
                }});
        }//清屏按钮实现
        if(findViewById(R.id.btnClear)!=null){btnClear= (Button) findViewById(R.id.btnClear);
            btnClear.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.clear();
                }});
        }//撤销按钮实现
        if (findViewById(R.id.btnPOP)!=null){btnPOP= (Button) findViewById(R.id.btnPOP);
            btnPOP.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {handWrite.doPOP();
                }});
        }}
}

Android小程序-涂鸦板相关推荐

  1. 用eclipse开发android小程序,【转】Eclipse 开发Android小程序遇到的问题总结

    用Eclipse 开发Android小程序遇到些小问题,在一边学习的过程中,将遇到的问题就记录一下,方面挺杂的,有关于程序出错的,关于linux应用的,有eclipse设置等- 1.ERROR: Ap ...

  2. android小程序:计算圆面积

    网络111 葛鹏 此程序主要实现的功能是输入圆的半径,点击计算按钮,程序便会自动计算出圆的面积. 知识点: 1.为什么要选择android. 2.了解各控件的用处. 3.避免在代码中死记硬背,注意灵活 ...

  3. 纯css svg 改变图片颜色 ios android 小程序

    本文出自: http://blog.csdn.net/wyk304443164 使用的是 filter drop-shadow 如果你只想兼容 Chrome 那么请看: http://www.zhan ...

  4. 做最漂亮的玩Android小程序第三版

    做最漂亮的[玩Android小程序]V3.0 相较于第二个版本的更新: 整体重构了API请求.因为写这个小程序的时间比较早了,那个时候的玩安卓开放API还未支持HTTPS,导致无法上线小程序,所以为了 ...

  5. 微信小程序做留言板mysql_微信小程序留言板功能源码

    微信小程序留言板功能源码?先说一下 1.到微信公众平台下载开发者工具.安装 2.appID与没有appID的区别是,appID可以用真机预览,而没有就不行 3.目录解释: a)pages放页面,每个都 ...

  6. android小程序源代码_我从 Android 转到微信小程序的思考

    大家好,好久不见,我是陈宇明,公众号「码个蛋」主理人. 由于最近工作比较忙,这两年来很少和大家分享自己的收获,期间大部分都是由「码个蛋」运营小组打理. 上个月我参加了腾讯官方举办的<小程序云开发 ...

  7. android小程序下线,关闭小程序

    请移步 新的文档.此文档以停止更新 关闭小程序 2.6.3开始支持此功能 小程序环境 注:此方法需要在集成SDK的原生工程中使用,在HBuilderX 内置基座运行无效果: 小程序中可调用plus.r ...

  8. android小程序_小程序踩坑记

    小程序踩坑记 希望这个文章能尽量记录下小程序的那些坑,避免开发者们浪费自己的生命来定位到底是自己代码导致的还是啥神秘的字节跳变原因. 前记 小程序大多数坑是同一套代码在不同平台上表现不一致导致的,微信 ...

  9. android小程序内核,小程序的运行环境:iOS(iPhone/iPad)、Android

    微信小程序运行在三端:iOS(iPhone/iPad).Android 和 用于调试的开发者工具. 三端的脚本执行环境以及用于渲染非原生组件的环境是各不相同的: 在 iOS 上,小程序逻辑层的 jav ...

最新文章

  1. 精选180+Python开源项目,随你选!做项目何愁没代码
  2. 20 个 jQuery 超酷视觉效果构建教程推荐
  3. Cpp / 拷贝构造函数的参数为什么必须使用引用类型
  4. oracle字符串使用函数,Oracle常用函数介绍之一(字符串)
  5. 标题文字超出2行 则隐藏后面显示省略号
  6. Struts2中我所遇到的内存溢出(java.lang.OutOfMemoryError)异常错误介绍
  7. FlvDownloader升级版DownloaderPlus发布
  8. GPIO应用开发方法【ZT】
  9. python集合运算_从零开始学Python - 第014课:常用数据结构之集合
  10. CentOS 服务器搭建 mediawiki
  11. c语言参数列表定义一个三维数组,C语言多维数组
  12. 【渝粤教育】国家开放大学2018年秋季 1302T护理科研方法 参考试题
  13. CHIL-SQL-UPDATE 语句
  14. 牛顿法和梯度下降法的效率对比
  15. 美国军方称密切关注量子加密,法国国防部重金投资量子技术
  16. java实现web ssh客户端
  17. dbfs和dbm的换算_dBm和dBV是怎么换算的,最好是有公式,还有是dBm,dBV,dBA,dB是什么单位?...
  18. 2022 年云计算发展趋势
  19. Windows Server 2012 磁盘管理
  20. Objective-C和iPHONE系列教程

热门文章

  1. Innosetup安装界面美化卸载界面美化
  2. 程序员最全进阶资源免费送
  3. 超级计算机还是超级烂尾?天河一号闲置近1年
  4. 字节输入输出流,字符输入输出流
  5. 关于 range.autofilter 和 VBA的 filter
  6. 00005在java结果输出_浅谈Java反序列化漏洞原理(案例未完善后续补充)
  7. 伯克利摘得最佳论文,陈丹琦、杨笛一等华人团队获杰出论文,ACL2022奖项公布...
  8. ffmpeg读取rtsp并保存到mp4文件
  9. 30W、45W、60W PD移动电源芯片方案+无线充方案
  10. Manjaro引导项丢失修复