Android项目刮刮奖详解(三)
前言
上一期我们已经实现了一个简易的刮刮卡功能,这一期我们来将其完善一下
目标
- 将刮刮奖的宽高改为合适高度
- 将刮刮奖位置居中
-
将信息层的图片换成文字(重点)
实现
-
将刮刮奖的宽高改为合适高度和将刮刮奖位置居中
这里其实很简单,我们直接到layout布局之中将大小修改一下即可,同时,在布局中利用
gravity
修改位置<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" tools:context="com.wan.guajiang.mainactivity"> <com.wan.guajiang.guaguaka android:layout_width="300dp" android:layout_height="100dp"/> </linearlayout>
将信息层的图片换成文字
之前我们信息层绘制的是中奖图片,如果没有图片怎么办?当然是直接拿文字来代替啦,canvas不仅可以画图片,还可以画文字,写文字
首先,我们来了解一下canvas的drawtext
方法参数
drawtext(string text, float x, floaty, paint paint);
text即使要写的文字内容,x,y是写的位置,需要注意的是,这里的x,y坐标并不是文字的左上角,而是一个与左下角比较接近的位置。大概在这里:如图
最后一个参数就是画笔了,这个画笔设置与之前相似,待会再补充一下
我们想要把文字写在信息层的正中间,x,y的坐标该怎么写呢?由上图可以知道,canvas使用drawtext
方法,xy的坐标其实是位于文字的左下角的,下图便是图解
相信这张图还是很好理解的,我们继续,开始写代码
-
首先,我们需要个文字内容
string message = "恭喜中奖,3万元!";
-
定义我们的画笔paint,对其进行相关设置
这里得提一下,我们需要一个rect矩形来得到文字内容的背景大小,也就是上图中的红色矩形,paint画笔中提供了一个方法
gettextbounds
,我们可以通过此方法来获得文字内容的背景大小
messagepaint.gettextbounds(string text,float start,float end,rect rect);上述代码的意思是,截取text文字中的从start到end的长度,将截取的长度和文字的高度形成一个矩形,rect矩形接收这个矩形
rect mbackground = new rect();//用来接收gettextbounds返回的矩形 paint messagepaint = new paint(); messagepaint.setcolor(color.red); messagepaint.setantialias(true); messagepaint.setstyle(paint.style.stroke); messagepaint.gettextbounds(message,0,message.length(),mbackground); messagepaint.settextsize(30);
-
计算x,y坐标,canvas使用drawtext写出文字
我们有两种方法来获得之前黑色矩形的长和宽,一种是使用getmeasured
,另一种使用mbitmap.get
方法来获得长和宽canvas.drawtext(message,getmeasuredwidth()/2-mbackground.width()/2,getmeasuredheight()/2+mbackground.height()/2,messagepaint);
或者:
canvas.drawtext(message,mbitmap.getwidth()/2-mbackground.width()/2,mbitmap.getheight()/2+mbackground.height()/2,messagepaint);
测试图
完整代码
public class guajiangview extends view { /** * 绘制线条的paint,即用户手指绘制path */ private paint moutterpaint = new paint(); /** * 记录用户绘制的path */ private path mpath = new path(); /** * 内存中创建的canvas */ private canvas mcanvas; /** * mcanvas绘制内容在其上 */ private bitmap mbitmap; private int mlastx; private int mlasty; private string message;//中奖信息 private rect mbackground;//文字背景矩形大小 private paint messagepaint = new paint();//文字画笔 private boolean isclear = false; public guajiangview(context context) { super(context); } public guajiangview(context context, @nullable attributeset attrs) { super(context, attrs); } public guajiangview(context context, @nullable attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); } public guajiangview(context context, @nullable attributeset attrs, int defstyleattr, int defstyleres) { super(context, attrs, defstyleattr, defstyleres); } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); log.d(tag, "onmeasure: 测量"); int width = getmeasuredwidth(); int height = getmeasuredheight(); // 初始化bitmap mbitmap = bitmap.createbitmap(width, height, bitmap.config.argb_8888);//以获得的宽高创建一个32位的bitmap mcanvas = new canvas(mbitmap);//以bitmap创建了一个画布 mcanvas.drawcolor(color.green);//设置画布的颜色为绿色 mbackground = new rect(); message = "恭喜中奖,3万元!"; messagepaint.setcolor(color.red); messagepaint.setantialias(true); messagepaint.setstyle(paint.style.stroke); messagepaint.gettextbounds(message,0,message.length(),mbackground); messagepaint.settextsize(30); // 设置画笔 moutterpaint.setcolor(color.blue); moutterpaint.setantialias(true);//使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢 moutterpaint.setdither(true);//图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰 moutterpaint.setstyle(paint.style.stroke); moutterpaint.setstrokejoin(paint.join.round);//圆角,平滑 moutterpaint.setstrokecap(paint.cap.round); //圆角 moutterpaint.setstrokewidth(20); // 设置画笔宽度 messagepaint.setcolor(color.red); } @override protected void ondraw(canvas canvas) { log.d(tag, "ondraw: 画"); canvas.drawtext(message,mbitmap.getwidth()/2-mbackground.width()/2,getmeasuredheight()/2+mbackground.height()/2,messagepaint); drawpath(); canvas.drawbitmap(mbitmap, 0,0, null); } private void drawpath() { log.d(tag, "drawpath: "); moutterpaint.setxfermode(new porterduffxfermode(porterduff.mode.dst_out)); mcanvas.drawpath(mpath, moutterpaint); } @override public boolean ontouchevent(motionevent event) { //当手指按到屏幕上的时候,path路径之中就使用moveto方法,移动到手指当前位置,invalidate刷新view,回调ondraw方法,(还没有画出来) //之后,手指移动,action是处于action_move的状态,path路径使用lineto方法(画直线), // 同时,将x,y坐标进行了更新,invalidate刷新view,回调ondraw方法,canvas通过drawpath使用画笔将path画了出来,之后如果用户没有抬起手指,则继续循环action_move中的步骤 int action = event.getaction(); int x = (int) event.getx();//获得x坐标 int y = (int) event.gety();//获得y坐标 switch (action){ case motionevent.action_down: mlastx = x; mlasty = y; mpath.moveto(mlastx, mlasty);//之后回调ondraw方法canvas将path break; case motionevent.action_move: mpath.lineto(x, y);//之后回调ondraw方法时canvas画直线到(x,y)该点 mlastx = x;//更新x坐标 mlasty = y;//更新y坐标 break; default:break; } invalidate();//刷新view,回调ondraw方法 log.d(tag, "ontouchevent: invalidate"); return true; } }
下一篇: 服务器干什么用的,服务器的作用与分类介绍