本文实例为大家分享了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; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。