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;
}
}
Android项目刮刮奖详解(三)的更多相关文章
- Android 之窗口小部件详解(三) 部分转载
原文地址:http://blog.csdn.net/iefreer/article/details/4626274. (一) 应用程序窗口小部件App Widgets 应用程序窗口小部件(Widget ...
- Android项目刮刮奖详解(二)
Android项目刮刮奖详解(一) 前言 上期我们简单地实现了一个画板的功能,用户可以在上面乱写乱画,其实,刮刮奖也是如此,用户刮奖的时候也是乱写乱画的. 刮刮奖原理 一共有两层画布,底层画布存放中奖 ...
- Android项目刮刮奖详解(四)
Android项目刮刮奖详解(三) 前言 上一期我们已经是完成了刮刮卡的基本功能,本期就是给我们的项目增加个功能以及美化一番 目标 增加功能 用户刮卡刮到一定程度的时候,清除遮盖层 在遮盖层放张图片, ...
- Android项目刮刮奖详解扩展篇——开源刮刮奖View的制作
Android项目刮刮奖详解(四) 前言 我们已经成功实现了刮刮奖的功能了,本期是扩展篇,我们把这个View直接定义成开源控件,发布到JitPack上,以后有需要也可以直接使用,关于自定义控件的知识, ...
- Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送
Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送, ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能
Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 我的本意是第二篇写Mob的shareSD ...
- Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!
Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...
- Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
随机推荐
- c# 通过MailHelper发送QQ邮件
发送的方法 appsetting内容 第一个是发送邮件qq账号,第二个是QQ邮箱的POP3/SMTP服务码(下面会说怎么获取),第三个是服务器,第四个是端口 获取QQ邮箱的POP3/SMTP服务码 1 ...
- DB2 数据库的安装配置及监控
一.DB2简介 IBM公司研制的一种关系型数据库系统.DB2主要应用于大型应用系统,具有较好的可伸缩性,可支持从大型机到单用户环境,应用于OS/2.Windows等平台下. DB2提供了高层次的数据利 ...
- [Java]LeetCode237. 删除链表中的节点 | Delete Node in a Linked List
Write a function to delete a node (except the tail) in a singly linked list, given only access to th ...
- 10.Git分支-分支管理(git branch命令)、分支开发工作流
1.分支管理 git branch 不仅可以创建和删除分支,还可以做一些其他工作. 1.不带参数的 git branch ,得到本地仓库当前的分支列表.并且会显示,当期所在的分支,也就是HEAD所指 ...
- 谷歌浏览器的各种插件网址Chrome插件(谷歌浏览器)-超级详细
各种各样的插件,可以查找对自己有用的,自行下载安装 http://chromecj.com/
- 【转】CGI
CGI是什么 (一): CGI是Common Gateway Interface 的简称.是一个用于定Web服务器与外部程序之间通信方式的标准,使得外部程序能生成HTML.图像或者其他内容,而服务器处 ...
- Jenkins 无法捕获构建脚本错误问题
Jenkins 版本 2.121.1 编写构建脚本执行,发现脚本执行出错,不会中断构建过程,导致最后展现的构建结果是错误的. 原因:构建脚本头部加入 #!/bin/bash ,jenkins会将脚本放 ...
- Quartz.NET学习笔记(三) 简单触发器
触发器是Quartz.NET的另外第一个核心元素,他有2种类型,简单触发器(Simple Trigger)和计划任务触发器(Cron Trigger), 一个触发器可以绑定一个任务. 通用触发器属性 ...
- JS判断客户端是否是iOS或者Android手机移动端(转载)
前言: 上午有一个移动端的项目负责人问我,在ios系统上样式出现问题,因为内核原因,我改来改去,在ios弄好了,但在安卓有问题了,突然想到了一种办法,既然ios是一种机型,安卓是一种机型,可以检测用户 ...
- 带着新人学springboot的应用03(springboot+mybatis+缓存 下)
springboot+mybatis+缓存,基本的用法想必是会了,现在说一说内部大概的原理. 稍微提一下mybatis,只要导入了mybatis的依赖,那么有个自动配置类就会生效,你可以去mybati ...