基于Android自定义控件实现刮刮乐效果

时间:2021-05-19

只是简单的实现了效果,界面没怎么做优化,不过那都是次要的啦!!相信大家都迫不及待的想看效果图了吧,

其中主要的彩票视图类和橡皮擦类都是通过代码的方式构建视图,布局文件就一个主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;@Overrideprotected 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() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubshowEnrie();}});}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 stubdouble d = Math.random() * 100;if (d < 50) {return 3;}if (d < 90) {return 2;}return 1;}@Overridepublic 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 stubthis.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 stubRelativeLayout.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 stubrubberBG = new RelativeLayout(mContext);// 得到彩票mRubberShow = new RubberShow(mContext, level);// 得到橡皮擦mButton = new Button(mContext);rubberBG.setId(rubberBGID);mButton.setId(mButtonID);mButton.setOnClickListener(new OnClickListener() {@Overridepublic 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}@Overrideprotected void onDraw(Canvas mCanvas) {// TODO Auto-generated method stubsuper.onDraw(mCanvas);if (isDraw) {Log.i("tag", "111");mCanvas.drawPath(mPath, paint);mCanvas.drawBitmap(bitmap, 0, 0, null);// 从起点开始画}}@Overridepublic 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;}}

以上代码附有注释,有哪里不明白的地方欢迎大家提出宝贵意见,谢谢大家一直以来对网站的支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章