android 自定义view实现圆盘抽奖的效果

废话不多说直接上代码。




import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;



public class ZhuanpanView extends View implements OnGlobalLayoutListener {

	private int width; // 转盘宽度
	private int padding; // 转盘内边距
	private int radius;// 半径
	private RectF rect; // 圆形矩形区域
	private Paint paint; // 图形画笔
	private Paint painttext; // 文字画笔
	private float angle = 0; // 起始旋转角度
	private int count = 8;// 扇形个数
	private float shanxingangle; // 扇形角度
	private String[] jianzhi = { "谢谢参与", "4999", "200", "50", "500", "9999",
			"100", "500" }; // 价值
	private String[] jianzhimc = { "豆差一点儿", "流量豆", "经验值", "流量豆", "流量豆", "流量豆",
			"流量豆", "经验值" }; // 价值名称
	private float speed = 0; // 每次旋转角度
	private float decrease = 1;
	private int jg = 50;
	private Handler handler = new Handler();

	public static final int NOMEAL = 0; // 正常状态
	public static final int ZHUANING = 1; // 正在转
	public static final int ENDING = 2; // 正在停止
	private int state = NOMEAL;

	private Bitmap backbitmap=BitmapFactory.decodeResource(getResources(), R.drawable.zhuanpanwaiyuan);

	private Runnable runnable = new Runnable() {

		@Override
		public void run() {

			ZhuanpanView.this.invalidate();
			handler.postDelayed(runnable, jg);
		}
	};

	public ZhuanpanView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);

		getViewTreeObserver().addOnGlobalLayoutListener(this);
		padding = getPaddingLeft();
		// 图形画笔
		paint = new Paint();
		paint.setAntiAlias(true); // 抗锯齿
		paint.setStyle(Paint.Style.FILL);
		//设置绘制的颜色,a代表透明度,r,g,b代表颜色值。
		paint.setARGB(255, 14 * 16 + 9, 14 * 16 + 9, 14 * 16 + 9);
		//设置画笔宽度
		paint.setStrokeWidth(4);

		// 文字画笔
		painttext = new Paint();
		painttext.setAntiAlias(true); // 抗锯齿
		//设置绘制文字的字号大小
		painttext.setTextSize(30);
		//设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE Style.FILL: 实心 STROKE:空心 FILL_OR_STROKE:同时实心与空心
		painttext.setStyle(Paint.Style.FILL);
		painttext.setARGB(255, 15 * 16 + 4, 6 * 16 + 12, 10);
		shanxingangle = 360.0f / 8;
	}

	public ZhuanpanView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public ZhuanpanView(Context context) {
		this(context, null);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		//计算最小值
		width = Math.min(getMeasuredHeight(), getMeasuredWidth());
		//
		radius = (width - padding * 2) / 2;
		rect = new RectF(padding, padding, width - padding, width - padding);
		setMeasuredDimension(width, width);
	}

	public void StartZhuan(int index) {
		state = ZHUANING;
		// 计算速度
		// 每项角度大小
		float angle = (float) (360 /count);
		// 中奖角度范围(因为指针向上,所以水平第一项旋转到指针指向,需要旋转210-270;)
		float from = 270 - (index + 1) * angle;
		float to = from + angle;
		// 停下来时旋转的距离
		float targetFrom =  0* 360 + from;
		/**
		 * 
		 *  (v1 + 0) * (v1+1) / 2 = target ;
		 *  v1*v1 + v1 - 2target = 0 ;
		 *  v1=-1+(1*1 + 8 *1 * target)/2;
		 * 
*/ float v1 = (float) (Math.sqrt(1 * 1 + 8 * 1 * targetFrom) - 1) / 2; float targetTo = 0 * 360 + to; float v2 = (float) (Math.sqrt(1 * 1 + 8 * 1 * targetTo) - 1) / 2; speed = (float) (v1 + Math.random() * (v2 - v1)); Log.v("speed",""+speed); //speed = 30; } public void EndZhuan() { state = ENDING; angle=0; } public int getState() { return state; } public boolean isZhan() { return speed != 0; } @Override protected void onDraw(Canvas canvas) { angle += speed; if (angle >= 360) { angle -= 360; } // 点击停止 if (state == ENDING) { speed -= decrease; // 速度的减少量 } if (speed <= 0) { speed = 0; state = NOMEAL; } //绘制背景 paint.setARGB(80, 13 * 16 + 12, 13 * 16 + 12, 13 * 16 + 12); //展示在屏幕上的区域 canvas.drawBitmap(backbitmap, null, new Rect(padding / 2, padding / 2, getMeasuredWidth() - padding / 2, getMeasuredWidth() - padding / 2), null); //canvas.drawCircle(radius + padding, radius + padding, radius, paint); // 绘制扇形 paint.setARGB(255, 13 * 16 + 12, 13 * 16 + 12, 13 * 16 + 12); paint.setStyle(Paint.Style.STROKE); float vOffset = 0; float hOffset = 0; float textwidth = 0; for (int i = 0; i < count; i++) { float startangle = i * shanxingangle + angle; canvas.drawArc(rect, startangle, shanxingangle, true, paint); // 绘制文本 Path path = new Path(); path.addArc(rect, startangle, shanxingangle); // 计算文字 painttext.setTextSize(35); painttext.setStyle(Paint.Style.FILL); painttext.setARGB(255, 15 * 16 + 4, 6 * 16 + 12, 10); textwidth = painttext.measureText(jianzhi[i]); vOffset = radius / 5; hOffset = (float) (radius * Math.PI / count - textwidth / 2); canvas.drawTextOnPath(jianzhi[i], path, hOffset, vOffset, painttext); painttext.setTextSize(30); painttext.setStyle(Paint.Style.FILL); painttext.setARGB(255, 9 * 16 + 12, 9 * 16 + 12, 9 * 16 + 12); textwidth = painttext.measureText(jianzhimc[i]); hOffset = (float) (radius * Math.PI / count - textwidth / 2); canvas.drawTextOnPath(jianzhimc[i], path, hOffset, vOffset + 30, painttext); } } @Override public void onGlobalLayout() { // 如果整个布局完成启动handler getViewTreeObserver().removeGlobalOnLayoutListener(this); handler.postDelayed(runnable, jg); } }

Activity中的一些逻辑


import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {

	// 逗你转
	private Button btn_zhan;
	private ZhuanpanView zview;



	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		zview =  this.findViewById(R.id.zview);
		btn_zhan = this.findViewById(R.id.btn_zhan);
		btn_zhan.setOnClickListener(this);
	}
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
			case R.id.btn_zhan:
				//判断是否为正常状态
				if (zview.getState() == ZhuanpanView.NOMEAL) {
					//开始转动
					zview.StartZhuan(1);
					//给按钮换一个背景
					btn_zhan.setBackgroundResource(R.drawable.icon_end);
				} else {
					//判断是否为正在转
					if (zview.getState() == ZhuanpanView.ZHUANING) {
						//停止
						zview.EndZhuan();
						btn_zhan.setBackgroundResource(R.drawable.icon_bengin);
					}
				}
				break;
		}

	}


}

布局代码就是一个button加一个背景图片。

你可能感兴趣的:(android 自定义view实现圆盘抽奖的效果)