简单实现Android绘图板

简单实现Android绘图板,第1张

概述下面这个实例通过前面学过的Paint、Canvas等2D绘画技术来实现一个简单的Android的绘图板

下面这个实例通过前面学过的Paint、Canvas等2D绘画技术来实现一个简单的AndroID的绘图板。

具体实现代码:

创建一个名为DrawVIEw的类,该类继承自androID.vIEw.VIEw类。在该类中,首先定义程序中所需的属性,然后添加构造方法,并重写onDraw(Canvas canvas)方法:
DrawVIEw.java:
[java] vIEw plain copy
package com.example.test; 
 
import androID.content.Context; 
import androID.graphics.Bitmap; 
import androID.graphics.Canvas; 
import androID.graphics.Paint; 
import androID.graphics.Path; 
import androID.util.AttributeSet; 
import 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;//画笔 
    Bitmap cacheBitmap=null;//定义一个内存中的图片,该图片将作为缓冲区 
    Canvas cacheCanvas=null;//定义cacheBitmap上的Canvas对象 
    /*
     * 功能:构造方法
     * */ 
    public DrawVIEw(Context context,AttributeSet attrs) { 
        super(context,attrs); 
         
    } 
     
    /*
     * 功能:重写onDraw方法
     * */ 
    @OverrIDe 
    protected voID onDraw(Canvas canvas) { 
        super.onDraw(canvas); 
     
    } 


创建布局文件,选择帧布局,并加入上面创建的继承了VIEw的自定义画图控件:
res/layout/main.xml
[HTML] vIEw plain copy
<?xml version="1.0" enCoding="utf-8"?>   
<FrameLayout xmlns:androID="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    androID:layout_wIDth="fill_parent" 
    androID:layout_height="fill_parent" 
    androID:ID="@+ID/frameLayout1" 
    androID:orIEntation="vertical" 
    > 
    <com.example.test.DrawVIEw  
        androID:ID="@+ID/drawVIEw1" 
        androID:layout_wIDth="match_parent" 
        androID:layout_height="match_parent"/> 
</FrameLayout> 

在DrawVIEw类的构造方法中,首先获取屏幕的高度和宽度,并创建一个与该VIEw相同大小的缓存区,然后创建一个新的画面,并实例化一个路径,再将内存中的位图绘制到cacheCanvas中,最后实例化一个画笔,并设置画笔的相关属性。
关键代码如下:
[java] vIEw plain copy
/*
     * 功能:构造方法
     * */ 
    public DrawVIEw(Context context,attrs); 
        vIEw_wIDth=context.getResources().getdisplayMetrics().wIDthPixels;//获取屏幕宽度 
        vIEw_height=context.getResources().getdisplayMetrics().heightPixels;//获取屏幕高度 
        //创建一个与该VIEw相同大小的缓存区 
        cacheBitmap=Bitmap.createBitmap(vIEw_wIDth,vIEw_height,Config.ARGB_8888); 
        cacheCanvas=new Canvas();//创建一个新的画布 
        path=new Path(); 
        //在cacheCanvas上绘制cacheBitmap 
        cacheCanvas.setBitmap(cacheBitmap); 
        paint=new Paint(Paint.DITHER_FLAG);//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);//设置默认笔触的宽度为1像素 
        paint.setAntiAlias(true);//设置抗锯齿效果 
        paint.setDither(true);//使用抖动效果 
    } 

在DrawVIEw类的onDraw()方法中,添加以下代码,用于设置背景颜色、绘制cacheBitmap、绘制路径以及保存当前绘图状态到栈中,并调用restore()方法恢复所保存的状态,关键代码如下:
[java] vIEw plain copy
/*
     * 功能:重写onDraw方法
     * */ 
    @OverrIDe 
    protected voID onDraw(Canvas canvas) { 
        super.onDraw(canvas); 
        canvas.drawcolor(0xFFFFFFFF);//设置背景色 
        Paint bmpPaint=new Paint();//采用默认设置创建一个画笔 
        canvas.drawBitmap(cacheBitmap,bmpPaint);//绘制cacheBitmap 
        canvas.drawPath(path,paint);//绘制路径 
        canvas.save(Canvas.ALL_SAVE_FLAG);//保存canvas的状态 
        //恢复canvas之前保存的状态,防止保存后对canvas执行的 *** 作对后续的绘制有影响 
        canvas.restore(); 
    } 

在Draw类中,重写ontouchEvent()方法,为该视图添加触摸事件监听器,在该方法中,首先获取触摸事件发生的位置,然后用switch语句对事件的不同状态添加响应代码,最后调用invalIDate()方法更新视图。具体代码如下:
[java] vIEw plain copy
@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: 
                //保证横竖绘制距离不能超过625 
                float dx=Math.abs(x-preX); 
                float dy=Math.abs(y-preY); 
                if(dx>5||dy>5){ 
                     //.quadTo贝塞尔曲线,实现平滑曲线(对比lineto) 
                    //x1,y1为控制点的坐标值,x2,y2为终点的坐标值 
                    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(); 
        return true;//返回true,表明处理方法已经处理该事件 
    } 

编写clear()方法,用于实现橡皮擦功能,具体代码如下:
[java] vIEw plain copy
public voID clear(){ 
        //设置图形重叠时的处理方式 
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
        //设置笔触的宽度 
        paint.setstrokeWIDth(50); 
    } 

编写保存当前绘图的save方法,在该方法中,调用saveBitmap()方法将当前绘图保存为PNG图片。save()方法的具体代码如下:
[java] vIEw plain copy
public voID save(){ 
        try{ 
            saveBitmap("myPitcture"); 
        }catch(IOException e){ 
            e.printstacktrace(); 
        } 
         
    } 

编写保存绘制好的位图的方法saveBitmap(),在该方法中,首先在SD卡上创建一个文件,然后创建一个文件输出流对象,并调用Bitmap类的compress()方法将绘图内容压缩为PNG格式输出到刚刚创建的文件输出流对象中,最后将缓冲区的数据全部写出到输出流中,并关闭文件输出流对象。saveBitmap()方法的具体代码如下:
[java] vIEw plain copy
private voID saveBitmap(String filename) throws IOException { 
        file file=new file(getSdpath()+filename+".png"); 
        file.createNewfile(); 
        fileOutputStream fileOS=new fileOutputStream(file); 
        //将绘图内容压缩为PNG格式输出到输出流对象中 
        cacheBitmap.compress(Bitmap.CompressFormat.PNG,100,fileOS); 
        fileOS.flush();//将缓冲区中的数据全部写出到输出流中 
        fileOS.close();//关闭文件输出流对象 
    } 
     
    //获得SD卡的根目录 
    public String getSdpath(){  
           file sdDir = null;  
           boolean sdCardExist = Environment.getExternalStorageState()    
                               .equals(androID.os.Environment.MEDIA_MOUNTED);   //判断sd卡是否存在  
 
 
 
 
           if   (sdCardExist)      //如果SD卡存在,则获取跟目录 
           {                                
             sdDir = Environment.getExternalStorageDirectory();//获取跟目录  
          }    
           return sdDir.toString();  
            
    } 

在程序中需要向SD卡上保存文件,那么需要在AndroIDManifest.xml文件中赋予相应的权限,
具体代码入下:
[HTML] vIEw plain copy
<!-- 执行SD卡检查的权限 --> 
<uses-permission androID:name="androID.permission.MOUNT_UNMOUNT_fileSYstemS"/> 
<!-- SD卡写入权限 --> 
<uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE"/> 

在res目录中,创建一个menu目录,并在该目录中创建一个名称为toolsmenu.xml的菜单资源文件,在该文件中编写实例中所应用的功能菜单,关键代码如下:
[HTML] vIEw plain copy
<?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> 

其中values/strings.xml中:
[HTML] vIEw plain copy
<?xml version="1.0" enCoding="utf-8"?> 
<resources> 
     
    <string name="app_name">test</string> 
    <string name="hello_world">Hello World!</string> 
    <string name="action_settings">Settings</string> 
    <string name="color">画笔颜色</string> 
    <string name="color_red">红色</string> 
    <string name="color_green">绿色</string> 
    <string name="color_blue">蓝色</string> 
    <string name="wIDth">画笔宽度</string> 
    <string name="wIDth_1">细</string> 
    <string name="wIDth_2">中</string> 
    <string name="wIDth_3">粗</string> 
    <string name="clear">擦除绘画</string> 
    <string name="save">保存绘画</string> 
     
</resources> 

在默认创建的MainActivity中,为实例添加选项菜单。
首先,重写onCreatoptionsMenu()方法,在该方法中,实例化一个MenuInflater对象,并调用该对象的inflate方法解析toolsmenu.xml的菜单资源文件。具体代码如下:
[java] vIEw plain copy
/*
     * 创建选项菜单
     * */ 
    @OverrIDe 
    public boolean onCreateOptionsMenu(Menu menu) { 
        MenuInflater inflator=new MenuInflater(this); 
        inflator.inflate(R.menu.toolsmenu,menu); 
        return super.onCreateOptionsMenu(menu); 
    } 
然后,重写onoptionsItemSelected方法,分别对各个菜单项被选择时做出相应的处理,具体代码如下:
[java] vIEw plain copy
/*
     * 当菜单项被选择时,做出相应的处理
     * */ 
    @OverrIDe 
    public boolean onoptionsItemSelected(MenuItem item) { 
        //获取自定义的绘图视图 
        DrawVIEw dv=(DrawVIEw)findVIEwByID(R.ID.drawVIEw1); 
        dv.paint.setXfermode(null);//取消擦除效果 
        dv.paint.setstrokeWIDth(1);//初始化画笔的宽度 
        switch(item.getItemID()){ 
            case R.ID.red: 
                dv.paint.setcolor(color.RED);//设置笔的颜色为红色 
                item.setChecked(true); 
                break; 
            case R.ID.green: 
                dv.paint.setcolor(color.GREEN);//设置笔的颜色为绿色 
                item.setChecked(true); 
                break; 
            case R.ID.blue: 
                dv.paint.setcolor(color.BLUE);//设置笔的颜色为蓝色 
                item.setChecked(true); 
                break; 
            case R.ID.wIDth_1: 
                dv.paint.setstrokeWIDth(1);//设置笔触的宽度为1像素 
                break; 
            case R.ID.wIDth_2: 
                dv.paint.setstrokeWIDth(5);//设置笔触的宽度为5像素 
                break; 
            case R.ID.wIDth_3: 
                dv.paint.setstrokeWIDth(10);//设置笔触的宽度为10像素 
                break; 
            case R.ID.clear: 
                dv.clear();//擦除绘画 
                break; 
            case R.ID.save: 
                dv.save();//保存绘画 
                break; 
        } 
        return true; 
    }   

运行效果如图

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的简单实现Android绘图板全部内容,希望文章能够帮你解决简单实现Android绘图板所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1143276.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存