android自定义控件实现刮刮乐效果
只是简单的实现了效果,界面没怎么做优化,不过那都是次要的啦!!
其中主要的彩票视图类和橡皮擦类都是通过代码的方式构建视图,布局文件就一个主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;
 }
}
                    
                

                
            
        
浙公网安备 33010602011771号