安卓 转盘功能添加

编程入门 行业动态 更新时间:2024-10-23 15:33:38

安卓 <a href=https://www.elefans.com/category/jswz/34/1740101.html style=转盘功能添加"/>

安卓 转盘功能添加


zhuanpanView.java

/** 说明:* 该类自定义了转盘类,可通过给定转盘中各个块的概率,控制指针的指向* 创建转盘时,需提供转盘背景图像panpic 和 指针图像panhandpic,二者为宽度相同的正方行* 转盘的块数由概率数组p[]限定* * 调用:* final zhuanpanView zhuanpan = new zhuanpanView(this) ; //创建转盘* int p[] = {20, 0, 20, 0, 30, 30};					  //p为转盘所有块的概率数组* zhuanpan.startRotate(p);                               //转盘指向对应块,返回值为块位置(从0顺时针计数) * - 若转盘处于旋转状态再次调用,则返回-1.*/import java.util.Random;import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;//自定义的转盘View  
public class zhuanpanView extends View implements Runnable
{  //界面需要的图片  private Bitmap panpic;  private Bitmap panhandpic;  public int width, height;						//转盘的宽度和高度//旋转矩阵private Matrix panRotate=new Matrix();			//可控制盘面的旋转private Matrix panhandTrans=new Matrix();  		//可控制指针的旋转private int degree=0;  							//旋转角度private float degreeSpeed=0;					//旋转角度变化增量,控制转盘转速由快到慢private int destdegree=360*6+60;				//最终停止角度位置private int offDegree = 0;						//角度偏移量,记录转盘指针前一次的位置public boolean flagRotate=false;				//标志转盘指针当前是否处于旋转状态private int centerX, centerY;					//旋转中心位置public static Random random = new Random();		//随机数对象//创建转盘控件-代码创建时,可调用该函数public zhuanpanView(Context context) {super(context);zhuanpanViewInit(context);  }  //创建转盘控件-XML布局创建控件时,会调用该函数public zhuanpanView(Context context, AttributeSet attrs) {super(context, attrs);zhuanpanViewInit(context);} //转盘控件自身的初始化private void zhuanpanViewInit(Context context){Resources r=context.getResources();//生成图片  panpic=BitmapFactory.decodeStream(r.openRawResource(R.drawable.table));  panhandpic=BitmapFactory.decodeStream(r.openRawResource(R.drawable.pointer)); //转盘大小自适应屏幕,已480屏幕宽度为基准float magnify = getMagnifyParams((Activity)context);panpic=resize(panpic, magnify);panhandpic=resize(panhandpic, magnify);width = panhandpic.getWidth();				//设置转盘的宽度height = panhandpic.getHeight();centerX = width/2;							//获取指针旋转的中心位置centerY = height/2;//用线程来刷新界面  Thread thread=new Thread(this);thread.start();  }//获取与屏幕适配的放大倍数private float getMagnifyParams(Activity activity){float magnify = 1f;//获取屏幕的宽度和高度WindowManager wm = activity.getWindowManager();int screenWidth = wm.getDefaultDisplay().getWidth();int screenHeight = wm.getDefaultDisplay().getHeight();int min = screenWidth < screenHeight ? screenWidth : screenHeight;	//取宽高较小的magnify = min/480f;Log.e("转盘自适应:", " ");Log.e("屏幕分辨率", screenWidth+"," + screenHeight);Log.e("转盘放大倍数", magnify+" " );return magnify;}//将Bitmap放大size倍private static Bitmap resize(Bitmap bitmap, float size) {Matrix matrix = new Matrix(); matrix.postScale(size, size); //长和宽放大缩小的比例Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);return resizeBmp;}//重写View类的onDraw()函数  @Override  protected void onDraw(Canvas canvas) {  canvas.drawBitmap(panpic, panRotate, null); 		//绘制出转盘panhandTrans.setRotate(degree+offDegree, centerX, centerY);	//转盘指针绕其中心旋转角度degreecanvas.drawBitmap(panhandpic, panhandTrans, null);	//绘制指针//控制位置的平移//panhandTrans.setTranslate(centerX-panhandpic.getWidth()/2, centerY-panhandpic.getHeight()/5*3);  }  //重写的run函数,用来控制转盘指针的转动,改变旋转的角度public void run() {  try {while(true){  if(flagRotate && degree < destdegree)	//控制转盘中的指针旋转到指定角度{this.degree += (int)degreeSpeed;  	//当前旋转到的角度//这个函数强制UI线程刷新界面  this.postInvalidate();  Thread.sleep(30); 					//每秒40次绘制degreeAccelerate();					//执行加减速处理if(degree >= destdegree) flagRotate = false;}}  } catch (InterruptedException e) {  e.printStackTrace();  }  }  //控制转盘中指针的旋转加减速private void degreeAccelerate(){if(degreeSpeed == 0) degreeSpeed = 1;if(degree<230)							//执行加速,大概130度范围加速到最大{if(degreeSpeed <= 20) degreeSpeed *= 1.19f;else if(degreeSpeed >= 21)degreeSpeed = 20.57f;}else if(destdegree - degree < 720) 		//执行减速{if(degreeSpeed > 1)degreeSpeed *= 0.9752f;else degreeSpeed = 1;}}//转盘数据重置public void reset(){offDegree = 0;degree=0;degreeSpeed=0;}//重置当前角度和转速,保存指针角度位置private void reset2(){offDegree = (degree+offDegree) % 360;		//先保存上次的角度偏移值degree=0;degreeSpeed=0;}//根据概率数组p控制转盘的旋转public int startRotate(int p[]){  if(flagRotate)							//如果转盘正处于旋转状态{Log.e("转盘选中位置", "-1");return -1;							//-1表示转盘当前不可用}reset2();								//获取转盘指针上次的角度偏移值,重置当前角度int select = set_destdegree(p);			//根据各块的给定概率设置旋转的最终角度和选中块位置Log.e("转盘选中位置", select+"");this.flagRotate=true;  					//开始旋转return select;							}  /*** 按默认概率,控制转盘旋转,* 转盘块数 = 概率数组p.length* startRotate(p)控制转盘旋转,返回值为转盘指针指向的块号*/public void startRotate1(){int p[] = {0, 20, 20, 20, 20, 20, 20, 20};startRotate(p);}//停止指针旋转,可不调用待其自动停止public void stopRotate(){  this.flagRotate=false;  }  //根据各部分的比例值,设置旋转最终停止位置public int set_destdegree(int p[]){int len = p.length;						//转盘中的总块数random.setSeed(random.nextLong());		//随机设置其随机种子,进一步随机化int countp = 0;							//统计所有块的总概率for(int j= 0; j < len; j++)countp += p[j];int num = random.nextInt(countp) + 1;	//生成1到countp之间的随机数//根据各块的比例值,将num转换为对应的块位置 iint tmp = 0;	//累计前面各块的概率和int i=0;for(; i<len && tmp < num; i++){tmp += p[i];						//累计概率if(num <= tmp)break;				//num在块p[i]的概率范围内}int partDegree = (int)(360/len);					//计算各块所占的角度大小int partRnddegree = random.nextInt(partDegree-3)+2; //块内角度随机偏移, -3)+2避免指向两块的交界处//块位置转化为块的对应角度destdegree = partDegree * i + 360*6 + partRnddegree;//指向选定块,多转6圈,块内角度随机destdegree -= offDegree;				//目标角度减少初始偏移return i;								//返回指针所指的块位置}
}  


添加转盘操作

添加:
=》1.
zhuanpanView.java、
pointer.png、table.png 
到项目=》2.
NewActivity.java中(待添加转盘的Activity)添加全局变量:
public zhuanpanView zhuanpan;			//添加转盘
public Handler handler;				//处理转盘的显示与隐藏NewActivity.onCreate(){}中添加:	——可调整 params.topMargin = 50; 的值修改转盘的垂直位置handler = new Handler() 
{@SuppressLint("HandlerLeak")@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 1:	//显示转盘if(zhuanpan==null)									//没有创建转盘,则创建{zhuanpan = new zhuanpanView(NewActivity.this);	//创建转盘//转盘的布局参数FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(zhuanpan.width, zhuanpan.height);params.topMargin = 50;							params.gravity = Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL/*Gravity.TOP*/;addContentView(zhuanpan, params);				//添加转盘到Activity}else zhuanpan.setVisibility(View.VISIBLE);			//已有,则显示break;case 2:	//隐藏转盘if(zhuanpan!=null)									//转盘存在{zhuanpan.setVisibility(View.INVISIBLE);			//隐藏zhuanpan.reset();								//转盘重置,回到初始状态}//		        		if(zhuanpan!=null && zhuanpan.getParent()!=null) ((ViewGroup)zhuanpan.getParent()).removeView(zhuanpan);break;case 3:	//启动转盘zhuanpan.startRotate1();break;}}
};=》3.
抽奖控制处添加:(调用函数进行控制)/*** 向父线程发送消息* what = 1, 显示转盘* what = 2, 隐藏转盘*/
private void zhuanpanControl(int what)
{Handler handler = NewActivity.instance.handler;	//用于子线程向父线程发送消息Message msg = new Message();msg.what = what;								handler.sendMessage(msg);						//通知handler处理事件
};/*** 启动转盘* @param p 各转盘块的概率 p = {10, 10, 10, 10, 15, 15, 15, 15}* @return  指针所指向的转盘块位置(从0顺时针计数)*/
private int zhuanpanStart(int[] p)
{return NewActivity.instance.zhuanpan.startRotate(p);
}


转盘图片:table.jpg、pointer.ppng
 


下载:





附录:(2015_08_17)

1、 zhuanpanView2.java

package com.linkstudio.popstar.script;/** 说明:* 该类自定义了转盘类,可通过给定转盘中各个块的概率,控制指针的指向* 创建转盘时,需提供转盘背景图像panpic 和 指针图像panhandpic,二者为宽度相同的正方行* 转盘的块数由概率数组p[]长度限定* * 默认设置:初始时,转盘指针指向0度位置,指向第一个块的中心位置(左边缘,设置pointerCenter = false;)* * 调用:* final zhuanpanView zhuanpan = new zhuanpanView2() ; //创建转盘* int p[] = {20, 0, 20, 0, 30, 30};					  //p为转盘所有块的概率数组* zhuanpan.startRotate(p);                               //转盘指向对应块,返回值为块位置(从0顺时针计数) * - 若转盘处于旋转状态再次调用,则返回-1.*/import java.util.Random;import android.util.Log;import com.hlge.lib.base.Component;// 自定义的转盘View
public class zhuanpanView2 implements Runnable
{Component panhand;private int degree = 0;  						// 旋转角度private float degreeSpeed = 0;					// 旋转角度变化增量,控制转盘转速由快到慢private int destdegree = 0;						// 最终停止角度位置private int offDegree = 0;						// 角度偏移量,记录转盘指针前一次的位置private float drawOffDegree = 0;				// 绘制偏移角度,指针指向距0度位置的度数,顺时针为正public boolean flagRotate = false;				// 标志转盘指针当前是否处于旋转状态private float centerX, centerY;					// 旋转中心位置private int blockNums = 1;						// 转盘中的总块数protected float blockDegree = 360;				// 一个转盘块占用的角度public static Random random = new Random();		// 随机数对象public boolean pointerCenter = true;			// 转盘指针是否指向第一块的中心位置,false:指向第一块的起始边缘// 转盘指针角度的调整public void degreeAdjust(float drawOffDegree){this.drawOffDegree = drawOffDegree - 0.3f;panhand.setRotate(centerX, centerY, -(degree + offDegree + drawOffDegree));}// 设置转盘指针的中心位置public void setCenter(float centerX, float centerY){this.centerX = centerX;this.centerY = centerY;panhand.setRotate(centerX, centerY, -(degree + offDegree + drawOffDegree));}// 创建转盘控件-代码创建时,可调用该函数,X/Y为位置调整public zhuanpanView2(Component panhand, float X, float Y){this.panhand = panhand;panhand.setXY((short) (panhand.x + X), (short) (panhand.y + Y));	// 重新调整位置this.centerX = panhand.width / 2;this.centerY = panhand.height / 2;}public boolean isRun = false;public void start(){Thread thread = new Thread(this);thread.start();isRun = true;}public void interrupt(){isRun = false;}// 重写的run函数,用来控制转盘指针的转动,改变旋转的角度public void run(){try{// while(isRun && (ScriptLib.luckyform != null || ScriptLib.sevenDayReward_Lucky != null))while (isRun){if (flagRotate && degree < destdegree)	// 控制转盘中的指针旋转到指定角度{this.degree += (int) degreeSpeed;  	// 当前旋转到的角度update();							// 转盘旋转时,角度变动执行相应逻辑panhand.setRotate(centerX, centerY, -(degree + offDegree + drawOffDegree));	// 转盘指针绕其中心旋转角度degree// panhand.setRotate(-(degree+offDegree+drawOffDegree));Thread.sleep(25); 					// 每秒25毫秒操作一次degreeAccelerate();					// 执行加减速处理if (degree >= destdegree){flagRotate = false;rotateStopDoing();				// 转盘停止转动时,执行逻辑interrupt();}}}}catch (InterruptedException e){e.printStackTrace();}}/** 更新操作,供子类重写 */public void update(){}/** 转盘停止转动时调用,供子类重写 */public void rotateStopDoing(){}// 控制转盘中指针的旋转加减速private void degreeAccelerate(){if (degreeSpeed == 0) degreeSpeed = 1;if (degree < 230)							// 执行加速,大概130度范围加速到最大{if (degreeSpeed <= 20)degreeSpeed *= 1.19f;else if (degreeSpeed >= 21) degreeSpeed = 20.57f;}else if (destdegree - degree < 720) 		// 执行减速{if (degreeSpeed > 1)degreeSpeed *= 0.9752f;elsedegreeSpeed = 1;}}// 转盘数据重置public void reset(){offDegree = 0;degree = 0;degreeSpeed = 0;}// 重置当前角度和转速,保存指针角度位置private void reset2(){offDegree = (degree + offDegree) % 360;		// 先保存上次的角度偏移值degree = 0;degreeSpeed = 0;}// 根据概率数组p控制转盘的旋转public int startRotate(int p[]){if (flagRotate)							// 如果转盘正处于旋转状态{Log.e("转盘选中位置", "-1");return -1;							// -1表示转盘当前不可用}reset2();								// 获取转盘指针上次的角度偏移值,重置当前角度int select = set_destdegree(p);			// 根据各块的给定概率设置旋转的最终角度和选中块位置Log.e("转盘选中位置", select + "");this.flagRotate = true;  				// 开始旋转start();return select;}/** 按默认概率,控制转盘旋转, 转盘块数 = 概率数组p.length startRotate(p)控制转盘旋转,返回值为转盘指针指向的块号 */public void startRotate1(){int p[] = { 0, 20, 20, 20, 20, 20, 20, 20 };startRotate(p);}// 停止指针旋转,可不调用待其自动停止public void stopRotate(){this.flagRotate = false;}/*** 获取转盘指针实时角度值,相对于第0块起始边角度位置*/public int curDegree(){float half = (pointerCenter ? (int)(blockDegree / 2) : 0);return (int)(degree + half + offDegree);}/*** 指针角度为degree时,所指的块位置*/public int blockIndex(float degree){return (int) (degree % 360 / blockDegree);}/*** 指针角度为degree时,所指的块位置(限定块角度大小partDegree)*/public int blockIndex(float degree, float partDegree){return (int) (degree % 360 / partDegree);}// 根据各部分的比例值,设置旋转最终停止位置public int set_destdegree(int p[]){blockNums = p.length;								// 转盘中的总块数random.setSeed(random.nextLong());					// 随机设置其随机种子,进一步随机化int countp = 0;										// 统计所有块的总概率for (int j = 0; j < blockNums; j++)countp += p[j];int num = random.nextInt(countp) + 1;				// 生成1到countp之间的随机数// 根据各块的比例值,将num转换为对应的块位置 iint tmp = 0;	// 累计前面各块的概率和int i = 0;for (; i < blockNums && tmp < num; i++){tmp += p[i];						// 累计概率if (num <= tmp) break;				// num在块p[i]的概率范围内}blockDegree = 360 / blockNums;			// 计算各块所占的角度大小int partRnddegree = random.nextInt((int)blockDegree - 9) + 5; 	// 块内角度随机偏移, -9)+5避免指向两块的交界处// 块位置转化为块的对应角度destdegree = (int)(blockDegree * i) + 360 * 6 + partRnddegree;	// 指向选定块,多转6圈,块内角度随机if (pointerCenter) destdegree -= (int)(blockDegree / 2);		// 相对于转盘背景少转动半个块内角destdegree -= offDegree;				// 目标角度减少初始偏移return i;								// 返回指针所指的块位置}
}


2、zhuanpanView.java

/*** 2015-8-11上午10:18:58* wangzhongyuan*/
package com.linkstudio.popstar.script;import android.util.Log;import com.hlge.lib.base.Component;
import com.hlge.lib.tool.SoundManager;/*** zhuanpanView 继承自转盘基础类zhuanpanView2,新增转盘指示灯、即时音效* -----* 2015-8-11 上午10:18:58 * wangzhongyuan*/
public class zhuanpanView extends zhuanpanView2
{private float nextDegree = 0;				// 下一处更新操作,角度位置zhuanpanLights16 tex;private boolean thisFormDebug = true;public zhuanpanView(Component panhand, float X, float Y, zhuanpanLights16 tex){super(panhand, X, Y);this.tex = tex;}/** 转盘指针指向各个块时,的更新操作 */public void update(){int degree = curDegree();if (degree > nextDegree){int index = blockIndex(degree, blockDegree / 2);	// (blockDegree/2)块大小的块索引if (index % 2 == 1) SoundManager.playSound("zhuandong.mp3", false);updateProcess(index);					// 显示指针所指块索引对应内容nextDegree += blockDegree / 2;			// 间隔一定角度值,执行更新操作}}String info = "";// 更新转盘显示信息private void updateProcess(int curBlock){if (thisFormDebug) info += curBlock + ", " + nextDegree + "; ";tex.index = curBlock;}/** 转盘停止转动时调用 */public void rotateStopDoing(){selectMessage();									//转盘停止转动调用逻辑SoundManager.playSound("zhuandong_js.mp3", false);	//播放转盘停止转动音效tex.index = -1;										//转盘重置,不绘制灯if (thisFormDebug){Log.e("转盘指针所指块变动:", info);info = "";}nextDegree %= 360;}/*** 转盘停止转动时调用,选中块处理逻辑,供子类调用*/public void selectMessage() {}
}

3、zhuanpanLights16.java

/*** 2015-8-11上午10:19:17* wangzhongyuan*/
package com.linkstudio.popstar.script;import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.hlge.lib.base.HlgeTexture;
import com.hlge.lib.base.SpineTexture;/*** Lights16 转盘指示灯* -----* 2015-8-11 上午10:19:17  * wangzhongyuan*/
public class zhuanpanLights16  extends HlgeTexture
{SpineTexture[] lights;public int index = -1, preIndex = -1;/** 创建Texture */public zhuanpanLights16(){super();lights = new SpineTexture[16];for (int i = 0; i < 16; i++)lights[i] = new SpineTexture("7", (14 + i) + "", true);}/** SpineTexture的绘制 */public void paint(SpriteBatch g){paint(g, x, -y);}/** SpineTexture的绘制 */public void paint(SpriteBatch g, float x, float y){if (index >= lights.length) index = 0;if (index >= 0 && lights[index] != null){g.setColor(color.toIntBits());		// 设置透明度if (parent != null){x += parent.width / 2;y += parent.height / 2;}//			if (index != preIndex)
//			{
//				preIndex = index;
//				if (lights[index].isPlayOver()) lights[index].rePlay(); // lights[index].spine.setAction(spine.actionId, false); //
//			}lights[index].paint(g, x, y);}}@Overridepublic void dispose(){for (int i = 0; i < lights.length; i++)if (lights[i] != null) lights[i].dispose();lights = null;}
}





更多推荐

安卓 转盘功能添加

本文发布于:2024-02-12 19:51:46,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1689189.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:转盘   功能

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!