只是简单的实现了效果,界面没怎么做优化,不过那都是次要的啦!!
其中主要的彩票视图类和橡皮擦类都是通过代码的方式构建视图,布局文件就一个主activity_main
上代码!!
 
主activity:
package com.guaguale;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.RelativeLayout;
 
/**
 * 主activity
 * 
 * @author HaoZai
 * 
 */
public class MainActivity extends Activity {
 
RelativeLayout container;
Button btn;
ErinieShow erinieShow;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
container = (RelativeLayout) findViewById(R.id.container);
btn = (Button) findViewById(R.id.enterbtn);
btn.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showEnrie();
}
 
});
}
 
private void showEnrie() {
// TODO Auto-generated method stub
// 移除所有子元素
container.removeAllViews();
// 产生一个彩票
int level = getLevel();
erinieShow = new ErinieShow(this, level);
container.addView(erinieShow, new LayoutParams(-2, -2));
}
 
/**
 * 获取奖励等级
 * 
 * @return
 */
private int getLevel() {
// TODO Auto-generated method stub
double d = Math.random() * 100;
if (d < 50) {
return 3;
}
if (d < 90) {
return 2;
}
return 1;
}
 
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
 
}
因为彩票视图相对复杂,所以通过自定义控件的方式,构造了一个彩票视图
package com.guaguale;
 
import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
 
/**
 * 彩票视图类
 * 
 * @author HaoZai
 * 
 */
public class ErinieShow extends RelativeLayout {
int level;
Context mContext;
RelativeLayout rubberBG;// 最底层奖励等级
RubberShow mRubberShow;// 橡皮擦
Button mButton;
int rubberBGID = 10001;
int mButtonID = 10002;
 
public ErinieShow(Context context, int level) {
super(context);
// TODO Auto-generated constructor stub
this.mContext = context;
this.level = level;
getElement();// 得到子元素
setElementLP();// 设置布局参数
 
// 初始化彩票了
setElementStyle();
 
// 设置橡皮檫了
setElement();
}
 
private void setElement() {
// 第一步在彩票上面画一个图层
mRubberShow.beginRubber(Color.parseColor("#d3d3d3"), 30, 10);
}
 
private void setElementStyle() {
switch (level) {
case 1:
rubberBG.setBackgroundResource(R.drawable.ic_launcher);
break;
case 2:
rubberBG.setBackgroundResource(R.drawable.ic_launcher);
break;
case 3:
rubberBG.setBackgroundResource(R.drawable.ic_launcher);
break;
 
default:
break;
}
}
 
/**
 * 给布局的子元素设置布局参数
 */
private void setElementLP() {
// TODO Auto-generated method stub
RelativeLayout.LayoutParams rubber_bg_lp = new RelativeLayout.LayoutParams(
350, 80);
rubberBG.setLayoutParams(rubber_bg_lp);
mRubberShow.setLayoutParams(rubber_bg_lp);
// rubber_bg_lp正下方
RelativeLayout.LayoutParams rubber_btn_lp = new RelativeLayout.LayoutParams(
-2, -2);
rubber_btn_lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
rubber_btn_lp.addRule(RelativeLayout.BELOW, rubberBGID);
mButton.setLayoutParams(rubber_btn_lp);
mButton.setClickable(false);
}
 
/**
 * 获取布局的子元素
 */
private void getElement() {
// TODO Auto-generated method stub
rubberBG = new RelativeLayout(mContext);// 得到彩票
mRubberShow = new RubberShow(mContext, level);// 得到橡皮擦
mButton = new Button(mContext);
rubberBG.setId(rubberBGID);
mButton.setId(mButtonID);
mButton.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
 
}
});
rubberBG.addView(mRubberShow);
addView(rubberBG);
addView(mButton);
}
}
 
橡皮檫类,用于将中奖信息上面的临时画布去掉
package com.guaguale;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Bitmap.Config;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
 
/**
 * 橡皮擦类
 * 
 * @author HaoZai
 * 
 */
public class RubberShow extends View {
private float TOUCH_TO_ERANCE;// 填充的最小距离,这个值越小画出来的曲线越柔和
private Bitmap bitmap;
private Canvas canvas;// 临时画布
private Paint paint;// 画笔
private Path mPath;// 鼠标的运行路径
private float mx, my;// 坐标
private boolean isDraw = false;
 
public RubberShow(Context context, int level) {
super(context);
// TODO Auto-generated constructor stub
}
 
@Override
protected void onDraw(Canvas mCanvas) {
// TODO Auto-generated method stub
super.onDraw(mCanvas);
if (isDraw) {
Log.i("tag", "111");
mCanvas.drawPath(mPath, paint);
mCanvas.drawBitmap(bitmap, 0, 0, null);// 从起点开始画
}
}
 
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isDraw) {
return true;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchDown(event.getX(), event.getY());
invalidate();// 刷新
break;
case MotionEvent.ACTION_MOVE:
touchMove(event.getX(), event.getY());
invalidate();// 刷新
break;
case MotionEvent.ACTION_UP:
touchUp(event.getX(), event.getY());
invalidate();// 刷新
break;
 
default:
break;
}
return true;
}
 
private void touchUp(float x, float y) {
// 画出路线
mPath.lineTo(x, y);
canvas.drawPath(mPath, paint);
mPath.reset();
}
 
private void touchMove(float x, float y) {
float dx = Math.abs(x - mx);
float dy = Math.abs(y - my);
// 两点之间的距离大于TOUCH_TO_ERANCE,就生成贝瑟尔曲线
if (dx >= TOUCH_TO_ERANCE || dy >= TOUCH_TO_ERANCE) {
// 用贝瑟尔实现平滑的曲线
// mPath.lineTo(dx, dy);
mPath.quadTo(mx, my, (x + mx) / 2, (y + my) / 2);
mx = x;
my = y;
}
 
}
 
private void touchDown(float x, float y) {
mPath.reset();// 重置路径
mPath.moveTo(x, y);
mx = x;
my = y;
 
}
 
/**
 * @param bgColor
 *            覆盖的背景颜色
 * @param paintStrokeWidth
 *            橡皮擦宽度
 * @param touchToLerance
 *            填充距离
 */
public void beginRubber(final int bgColor, final int paintStrokeWidth,
float touchToLerance) {
TOUCH_TO_ERANCE = touchToLerance;
paint = new Paint();
// 画笔划过的痕迹变为透明
paint.setColor(Color.BLACK);// 此处不能为透明
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
paint.setAntiAlias(true);// 变为光滑
paint.setStyle(Style.STROKE);// 空心和实心
paint.setStrokeJoin(Paint.Join.ROUND);// 前面圆角
paint.setStrokeCap(Paint.Cap.ROUND);// 后圆角
paint.setStrokeWidth(paintStrokeWidth);// 画笔宽度
 
// 覆盖
LayoutParams layoutParams = getLayoutParams();
int height = layoutParams.height;
int width = layoutParams.width;
// if(layoutParams.height ==LayoutParams.MATCH_PARENT){
//
// }else{
//
// }
 
// 记录痕迹
mPath = new Path();
bitmap = Bitmap.createBitmap(width, height, Config.ARGB_4444);// 4444占内存更少
canvas = new Canvas(bitmap);
canvas.drawColor(bgColor);
isDraw = true;
}
}

android自定义控件实现刮刮乐效果的更多相关文章

  1. android自定义控件(4)-自定义水波纹效果

    一.实现单击出现水波纹单圈效果: 照例来说,还是一个自定义控件,观察这个效果,发现应该需要重写onTouchEvent和onDraw方法,通过在onTouchEvent中获取触摸的坐标,然后以这个坐标 ...

  2. 【Android界面实现】使用Canvas对象实现“刮刮乐”效果

    在淘宝.京东等电商举办活动的时候,常常能够看到在移动client推出的各种刮奖活动,而这样的活动也受到了非常多人的喜爱.从client的体验来说,这样的效果应该是通过网页来实现的,那么,我们使用And ...

  3. Android 自定义控件实现刮刮卡效果 真的就只是刮刮卡么

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40162163 , 本文出自:[张鸿洋的博客] 很久以前也过一个html5的刮刮卡 ...

  4. Android打造完美的刮刮乐效果控件

    技术:Android+Java   概述 趁着元旦假期之际,首先在这里,我祝福大家在新的2019年都一个个的新健康,新收入,新顺利,新如意!!! 上一偏,我介绍了用Xfermode实现自定义圆角和椭圆 ...

  5. HTML5 简单实现刮刮乐效果

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Android 撕衣服(刮刮乐游戏)

    项目简单介绍: 该项目为撕衣服,相似刮刮乐游戏 具体介绍: 用户启动项目后.载入一张图片,当用户点击图片的时候,点击的一片区域就会消失.从而显示出在这张图片以下的图片 这个小游戏相似与刮奖一样,刮开涂 ...

  7. [cocos2d-js]cc.RenderTexture几种用法(数字图片、刮刮乐效果)

    [转]http://blog.csdn.net/realcrazysun1/article/details/42393629 本文基于cocos2d-js 3.0版本引擎开发 RenderTextur ...

  8. Android 自定义View修炼-【2014年最后的分享啦】Android实现自定义刮刮卡效果View

    一.简介: 今天是2014年最后一天啦,首先在这里,我祝福大家在新的2015年都一个个的新健康,新收入,新顺利,新如意!!! 上一偏,我介绍了用Xfermode实现自定义圆角和椭圆图片view的博文& ...

  9. iOS-仿支付宝刮刮乐效果

    概述 仿支付宝刮刮乐效果, 可以按照自己需求更改展示刮出来的效果的view(即刮开后刮刮乐效果展示) 详细 代码下载:http://www.demodashi.com/demo/10673.html ...

  10. Android 自己定义控件实现刮刮卡效果 真的就仅仅是刮刮卡么

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40162163 , 本文出自:[张鸿洋的博客] 非常久以前也过一个html5的刮刮 ...

随机推荐

  1. BIOS与UEFI、MBR和GPT介绍

    操作步骤: UEFI是取代传统BIOS的,全称“统一的可扩展固件接口”.MBR则是传统的分区表类型,最大的缺点则是不支持容量大于2T的硬盘.GPT则弥补了MBR这个缺点,最大支持18EB的硬盘,是基于 ...

  2. 深入理解c语言_从编译器的角度考虑问题_纪念Dennis Ritchie先生

    开源中国: Dennis Ritchie教授过世了,他发明了C语言,一个影响深远并彻底改变世界的计算机语言.一门经历40多年的到今天还长盛不训的语言,今天很多语言都受到C的影 响,C++,Java,C ...

  3. web.xml配置详解之欢迎页面和错误页面

    <!-- 应用的欢迎页面  采用list的方式罗列欢迎页面, 系统会从第一个找到最后一个,找到了文件就不继续往下找了.优先显示前边的. --> <welcome-file-list& ...

  4. 知识面 z

    http://blog.csdn.net/sxhelijian/article/details/23163683 有了较宽和知识面,面对复试中不知道的问题,回答可以是:“这个问题,直接回答我没有把握, ...

  5. POJ 1773 Parity game 带权并查集

    分析:带权并查集,就是维护一堆关系 然后就是带权并查集的三步 1:首先确定权值数组,sum[i]代表父节点到子节点之间的1的个数(当然路径压缩后代表到根节点的个数) 1代表是奇数个,0代表偶数个 2: ...

  6. lightoj 1007

    预先处理好phi数组和前缀和,水题. #include<cstdio> #include<string> #include<cstring> #include< ...

  7. [九度OJ]1011.最大连续子序列

    原题链接:http://ac.jobdu.com/problem.php?pid=1011 题目描述:     给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ N ...

  8. NOIP2002 字串变换

    题二 字串变换 (存盘名: NOIPG2) [问题描述]: 已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则): A1$ -> B1$ A2$ -> B2$ 规则的含义为: ...

  9. 微软Azure 存储管理器的简单介绍

    Windows Azure存储用户经常希望能够在“管理器”中查看他们的数据,管理器指的是一款可用于显示存储帐户数据的工具.我们之前提供了我们所知的存储管理器列表.在本文中,我们将对此列表进行更新,使其 ...

  10. Drupal安装及使用问题解决列表

    #1. 启动 Clean URL 修改Apache的配置文件(如httpd.conf),打开 LoadModule rewrite_module modules/mod_rewrite.so选项.然后 ...