本文实例为大家分享了android自定义view实现简易画板的具体代码,供大家参考,具体内容如下

自定义view实现简易画板效果,功能包括清空、选择颜色,选择大小,效果如下

画板布局:

<?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:gravity="center"
    android:orientation="vertical"
    tools:context=".mainactivity">
    <!-- 这是一个自定义组合控件,包含涂鸦板及右边三个按钮 -->
    <com.android.mytest.graffitibroadlayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</linearlayout>

自定义view graffitibroadlayout 布局文件 view_graffiti.xml:

<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:baselinealigned="false">
    <!-- 自定义涂鸦板view -->
    <com.android.mytest.graffitiview
        android:id="@+id/graffiti_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" />

    <androidx.recyclerview.widget.recyclerview
        android:id="@+id/recycler_view"
        android:visibility="gone"
        android:layout_gravity="right"
        android:layout_marginright="100dp"
        android:layout_width="80dp"
        android:layout_height="wrap_content"/>
    <!-- 右侧三个按钮 清空、颜色、粗细 -->
    <linearlayout
        android:layout_gravity="right"
        android:orientation="vertical"
        android:layout_width="100dp"
        android:layout_height="match_parent">
        <button
            android:id="@+id/clear_all"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <button
            android:id="@+id/select_color"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <button
            android:id="@+id/select_size"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </linearlayout>

</framelayout>

画板布局中包括一个 自定义涂鸦view,recyclerview用于显示选择颜色、大小,三个按钮,分别是:
清空、选择颜色、选择大小

// 继承linearlayout 
public class graffitibroadlayout extends linearlayout {
    
    private final int[] colors = {r.color.red,r.color.green,r.color.blue};// 颜色数组
    private final int[] sizes = {5,10,15,20};// 画笔size数组

    private context mcontext;
    private view mview;
    private graffitiview mgraffitiview;
    private recyclerview mrecyclerview;

    public graffitibroadlayout(context context) {
        super(context);
    }

    public graffitibroadlayout(context context, @nullable attributeset attrs) {
        super(context, attrs);
        mcontext = context;
        // 获取布局view
        mview = layoutinflater.from(context).inflate(r.layout.view_graffiti, this,true);
        initview();// 初始化并设置点击事件
    }

    private void initview() {
        button clearallbtn = mview.findviewbyid(r.id.clear_all);
        button selectcolorbtn = mview.findviewbyid(r.id.select_color);
        button selectsizebtn = mview.findviewbyid(r.id.select_size);
        mgraffitiview = mview.findviewbyid(r.id.graffiti_view);
        mrecyclerview = mview.findviewbyid(r.id.recycler_view);
        mrecyclerview.setlayoutmanager(new linearlayoutmanager(mcontext));

        // 点击清空 画板
        clearallbtn.setonclicklistener(v -> mgraffitiview.clearallpath());
        // 选择画笔颜色
        selectcolorbtn.setonclicklistener(v -> {
            graffitiadapter adapter = new graffitiadapter(mcontext,colors,1);
            mrecyclerview.setadapter(adapter);
            mrecyclerview.setvisibility(visible);
        });
        // 选择画笔大小
        selectsizebtn.setonclicklistener(v -> {
            graffitiadapter adapter = new graffitiadapter(mcontext,sizes,2);
            mrecyclerview.setadapter(adapter);
            mrecyclerview.setvisibility(visible);
        });

    }
    // 自定义adapter
    class graffitiadapter extends recyclerview.adapter<graffitiviewholder>{

        context mcontext;
        int[] cs;
        int type;// 用于判断显示颜色 还是 选择大小

        public graffitiadapter(context mcontext, int[] cs,int type) {
            this.mcontext = mcontext;
            this.cs = cs;
            this.type = type;
        }

        @nonnull
        @override
        public graffitiviewholder oncreateviewholder(@nonnull viewgroup parent, int viewtype) {
            // 获取 item 布局
            view view = layoutinflater.from(mcontext).inflate(r.layout.item_recycler_graffiti,parent,false);
            return new graffitiviewholder(view);
        }

        @override
        public void onbindviewholder(@nonnull graffitiviewholder holder, int position) {
            if(type == 1){// 颜色
                holder.view.setbackgroundresource(cs[position]);
                holder.click.setonclicklistener(v -> {
                    // 设置画笔颜色
                    mgraffitiview.setpaintcolor(cs[position]);
                    mrecyclerview.setvisibility(gone);
                });
            }else if(type == 2){// size
                viewgroup.layoutparams lp = holder.view.getlayoutparams();
                lp.height = sizes[position]*2;
                holder.view.setlayoutparams(lp);
                holder.view.setbackgroundresource(r.color.black);
                holder.click.setonclicklistener(v -> {
                    // 设置画笔size
                    mgraffitiview.setpaintsize(sizes[position]);
                    mrecyclerview.setvisibility(gone);
                });
            }

        }

        @override
        public int getitemcount() {
            return cs.length;
        }
    }

    static class graffitiviewholder extends recyclerview.viewholder{
        view view;
        linearlayout click;
        public graffitiviewholder(@nonnull view itemview) {
            super(itemview);
            view = itemview.findviewbyid(r.id.item_view);
            click = itemview.findviewbyid(r.id.click_view);
        }
    }

}

item_recycler_graffiti.xml 布局文件

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_margintop="10dp"
    android:layout_height="50dp"
    android:gravity="center">
    <linearlayout
        android:id="@+id/click_view"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="uselessparent">
        <view
            android:id="@+id/item_view"
            android:layout_width="match_parent"
            android:layout_height="40dp"/>
    </linearlayout>

</linearlayout>

自定义涂鸦view:

public class graffitiview extends view {

    private final context mcontext;
    private canvas mcanvas;// 
    private bitmap mbitmap;// 用于保存绘制过的路径的 bitmap
    private paint mpaint;// 画笔
    private path mpath;// 触摸时的路径

    private int width,height;

    public graffitiview(context context) {
        this(context,null);
    }

    public graffitiview(context context, @nullable attributeset attrs) {
        super(context, attrs);
        mcontext = context;
        init();
    }

    private void init() {
        // 初始化 画笔
        mpaint = new paint();
        mpaint.setcolor(mcontext.getcolor(r.color.green));//画笔颜色
        mpaint.setantialias(true);// 抗锯齿
        mpaint.setdither(true);// 抖动处理
        mpaint.setstrokejoin(paint.join.round);//画笔连接处 圆弧
        mpaint.setstrokecap(paint.cap.round);//画笔拐弯处风格 圆弧
        mpaint.setstyle(paint.style.stroke);//画笔格式
        mpaint.setstrokewidth(10f);//画笔宽度

        mpath = new path();
    }

    @override
    protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
        super.onmeasure(widthmeasurespec, heightmeasurespec);
        width = getmeasuredwidth();
        height = getmeasuredheight();
        if(mbitmap == null){
            // 初始化 bitmap
            mbitmap = bitmap.createbitmap(width,height, bitmap.config.argb_4444);
        }
        if(mcanvas == null){
            mcanvas = new canvas(mbitmap);
        }
    }

    @override
    protected void ondraw(canvas canvas) {
        super.ondraw(canvas);
        // 绘制路径 
        // 因为每次触摸都会生成一条新的路径,直接绘制会使原路径消失,因此
        mcanvas.drawpath(mpath,mpaint);// 先将路径绘制到 bitmap 上,再绘制到当前画布中
        canvas.drawbitmap(mbitmap, 0,0,mpaint);// 将bitmap绘制到当前画布中
    }

    /**
     * 清除之前所有路径
     */
    public void clearallpath(){
        mbitmap = bitmap.createbitmap(width,height, bitmap.config.argb_4444);
        mcanvas = new canvas(mbitmap);
        mpath.reset();
        invalidate();
    }

    /**
     * 设置画笔颜色
     * @param resource id
     */
    public void setpaintcolor(int resource){
        mpaint.setcolor(mcontext.getcolor(resource));
    }

    /**
     * 设置画笔大小
     * @param size size
     */
    public void setpaintsize(int size){
        mpaint.setstrokewidth(size);
    }

    @suppresslint("clickableviewaccessibility")
    @override
    public boolean ontouchevent(motionevent event) {
        int action = event.getaction();
        float x = event.getx();
        float y = event.gety();
        switch (action){
            case motionevent.action_down:
                mpath = new path();// 每次触摸 生成一条新的路径
                mpath.moveto(x,y);
                break;
            case motionevent.action_move:
                mpath.lineto(x,y);
                invalidate();
                break;
        }
        return true;
    }
}

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