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 的背景. ...
随机推荐
- Centos7 编译安装 Nginx Mariadb Asp.net Core2 (实测 笔记 Centos 7.3 + Openssl 1.1.0h + Mariadb 10.3.7 + Nginx 1.14.0 + Asp.net. Core 2 )
环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G,双网卡) 系统版本:CentOS-7-x86_64-Minimal-1611.iso 安装步骤: 1.准备 1.0 查看硬 ...
- IIS中 flv、swf 文件无法播放
解决方案: 1.服务器安装flash,这是必须的. 2.MIME类型添加两个:名称.swf,值application/x-shockwave-flash:名称.flv,值flv-application ...
- B4 and After: Managing Hierarchy, Partitioning, and Asymmetry for Availability and Scale in Google’s Sofware-Defined WAN
B4及之后:为谷歌软件定义WAN的可用性和扩展管理层次化.划分和不对称 本文为SIGCOMM 2018会议论文,由谷歌提供. 笔者翻译了该论文.由于时间仓促,且笔者英文能力有限,错误之处在所难免:欢迎 ...
- Mesos源码分析(3): Mesos Master的启动之二
2. process::firewall::install(move(rules));如果有参数--firewall_rules则会添加规则 对应的代码如下: // Initialize fire ...
- 微服务(Microservices)和服务网格(Service Mesh)架构概念整理
注:文章内容为摘录性文字,自己阅读的一些笔记,方便日后查看. 微服务(Microservices) 在过去的 2016 年和 2017 年,微服务技术迅猛普及,和容器技术一起成为这两年中最吸引眼球的技 ...
- 像屎一样的 Spring Boot入门,总算有反应了
我特么最烦的就是现在Java不知道抽什么风,喜欢用maven这种,怎么搞都会有错误提示的玩意.搞个spring boot,官方的所谓http://start.spring.io/生成的项目启动不了. ...
- 搭建Windows故障转移群集
标签:SQL SERVER/MSSQL SERVER/数据库/DBA/windows 概述 本章内容主要讲述搭建windows故障转移群集 环境: 域服务器:windows server 2008 R ...
- Kubernetes — 我的第一个容器化应用
而在这篇文章中,我们就来扮演一个应用开发者的角色,使用这个 Kubernetes 集群发布第一个容器化应用. 在开始实践之前,我先给你讲解一下 Kubernetes 里面与开发者关系最密切的几个概念. ...
- [Swift]LeetCode466. 统计重复个数 | Count The Repetitions
Define S = [s,n] as the string S which consists of n connected strings s. For example, ["abc&qu ...
- JDK 8u131
JDK 8u131 发布了.Java SE 8u131 包括重要的安全修复和bug修复.Oracle 强烈建议所有 JavaSE 8 用户升级到此版本.此次完整版本号为1.8.0_131-b11. J ...