Android 美食大转盘详解流程
效果视频
前言
你还在为明天吃什么而烦恼嘛
美食大赏帮你解决选择困难症
帮你做出最佳的选择
做吃货,我们是认真的
美食大转盘
本示例使用SurfaceView绘制而成,接下来逐步分析,
文末会贴出全部代码``文末会贴出全部代码``文末会贴出全部代码
初始化SurfaceView
private void init() {
mSurfaceHolder = this.getHolder();
// 管理SurfaceView的生命周期
mSurfaceHolder.addCallback(this);
this.setFocusable(true);
this.setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
}
测量
通过获取高、宽,然后减去mPadding 的长度获取到控件中心点,然后存储测量的宽、高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = Math.min(getMeasuredWidth(), getMeasuredHeight());
mPadding = getPaddingLeft();
mRadius = width - mPadding * 2;
// 中心点
mCenter = width / 2;
setMeasuredDimension(width, width);
}
绘制
绘制圆盘背景
设置背景图片
private Bitmap mBgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.turntable_bgcolor );
绘制背景突出部分
private void drawBgColor() {
mCanvas.drawColor(0xFFFFFFFF);
mCanvas.drawBitmap(mBgBitmap, null, new Rect(mPadding / 2, mPadding / 2, getMeasuredWidth() - mPadding / 2, getMeasuredWidth() - mPadding / 2), null);
}
绘制盘块
private void drawArea() {
// 起始角度
float tempAngle = mStartAngle;
// 每个盘块绘制的角度
float sweepAngele = 360 / mItemCount;
for (int i = 0; i < mItemCount; i++) {
mArcPaint.setColor(itemColors[i]);
// 绘制盘块
mCanvas.drawArc(mRange, tempAngle, sweepAngele, true, mArcPaint);
// 绘制文本
drawText(tempAngle, sweepAngele, itemCharString[i]);
// 绘制图标
drawIcon(tempAngle, mBitmaps[i]);
tempAngle += sweepAngele;
}
mStartAngle += mSpeed;
// 如果需要停止,让转速逐渐变小直到0
if (isShouldEnd) {
mSpeed -= mDifferSpeed;
}
if (mSpeed <= 0) {
mSpeed = 0;
isShouldEnd = false;
}
}
绘制盘块内文字
private void drawText(float tempAngle, float sweepAngele, String itemTextStr) {
Path path = new Path();
path.addArc(mRange, tempAngle, sweepAngele);
// 利用水平偏移量让文字居中
float textWidth = mTextPaint.measureText(itemTextStr);
int hOffset = (int) (mRadius * Math.PI / mItemCount / 2 - textWidth / 2);
// 利用垂直偏移量让文字向圆心靠拢
int vOffset = mRadius / 2 / 6;
mCanvas.drawTextOnPath(itemTextStr, path, hOffset, vOffset, mTextPaint);
}
绘制盘块内图标
private void drawIcon(float tempAngle, Bitmap bitmap) {
// 约束图片的宽度,为直径的1/8,可以作为可变参数设置
int imgWidth = mRadius / 8;
// 获取弧度值
float angle = (float) ((tempAngle + 360 / mItemCount / 2) * Math.PI / 180);
// 约定图片位置在直径1/4处
int x = (int) (mCenter + mRadius / 4 * Math.cos(angle));
int y = (int) (mCenter + mRadius / 4 * Math.sin(angle));
// 确定图片位置
Rect rect = new Rect(x - imgWidth / 2, y - imgWidth / 2, x + imgWidth / 2, y + imgWidth / 2);
mCanvas.drawBitmap(bitmap, null, rect, null);
}
开始旋转转盘
public void Start(int index) {
if (isStart()) {
return;
}
if (index < 0) {
mSpeed = 50 * (1 + Math.random() * (0.5));
isShouldEnd = false;
return;
}
}
停止旋转转盘
public void Stop() {
if (isShouldEnd()) {
return;
}
// 将初始角度重置
mStartAngle = 0;
isShouldEnd = true;
}
自定义转盘等份
因为我们要根据需要制作不同等份的转盘,需要跟用户产生交互,所有需要暴露一个方法供用户选择
public void InitNumber(int number){
if (number <= 0){
return;
}
if (number % 2 == 0){
InitArea(number);
}
}
本示例以4,6,8等份为例
private void InitArea(int number){
switch (number){
case 4:
fourParts();
break;
case 6:
sixParts();
break;
case 8:
eightParts();
break;
default:
sixParts();
}
}
每一次选择转盘等份,都需要对View进行重绘,需要多次改变图片数量,所以我们将图片设置成一个公共的方法,避免内存浪费
private void fourParts(){
mItemCount = 4;
itemCharString = new String[]{"粉条", "面条", "米饭", "粥",};
itemImages = new int[]{R.drawable.fen, R.drawable.mian, R.drawable.rice, R.drawable.tang};
itemColors = new int[]{0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01};
InitImage(mItemCount,itemImages);
}
private void InitImage(int count,int[] item){
mBitmaps = new Bitmap[mItemCount];
for (int i = 0; i < count; i++) {
mBitmaps[i] = BitmapFactory.decodeResource(getResources(), item[i]);
}
}
控件引用
布局引用
XML布局文件内引用如下,其中中间的指针为图片类型
<com.franzliszt.foodturntable.Turntable
android:id="@+id/TurnTable"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
android:layout_margin="10dp"
android:layout_centerInParent="true"/>
<ImageView
android:id="@+id/StartAndEnd"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:class="lazy" data-src="@drawable/start"
android:onClick="Start"/>
Activity 引用
默认设置8等份,如果自定义多种等份,默认必须为最大的等份,不然会出现区域空白
turntable.InitNumber( 8 );
图标切换
对开始与暂停图标进行切换,根据点击次数进行切换
public void Start(View view) {
count++;
if (count % 2 == 0) {
turntable.Stop();
StartIcon();
} else {
turntable.Start( -1 );
StopIcon();
}
}
更换转盘等份
首先提供三个RadioButton供用户选择,然后通过SharedPreferences
进行存储数据,有关SharedPreferences
封装的知识,请移步到另一篇博文Android SharedPreferences存取操作以及封装详解
private void SelectNumber() {
RG.setOnCheckedChangeListener( new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.fourParts:
sp.PutData( context, "num", 4 );
break;
case R.id.sixParts:
sp.PutData( context, "num", 6 );
break;
case R.id.eightParts:
sp.PutData( context, "num", 8 );
break;
}
}
} );
}
然后取出数据,并回调等份数值即可
public void Confirm(View view) {
RevealAnim( view );
loadingView.setVisibility( View.VISIBLE );
startLoading();
startPercentMockThread();
int num = (int) sp.GetData( context, "num", 0 );
turntable.InitNumber( num );
}
沉浸式体验
效果图
沉浸式体验即标题栏与系统状态栏主题一致我们分为以下几个步骤完成以上效果
建立一个样式
首先我们需要建立一个标题栏为空的样式,我们有两种方式去实现
第一种,使用系统提供样式
<style name="NotActionBar_1" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
第二种,直接使用标志进行设置
其实第一种的源码就是第二种,(废话文学)
<style name="NotActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
引用空标题栏样式
我们需要在我们要隐藏标题栏的Activity中引用如下代码android:theme="@style/NotActionBar"
配置图如下,地址:清单文件中进行配置
自定义标题栏
我们隐藏了标题栏之后,我们需要自定义一个自己喜欢的风格的标题栏
推荐使用ToolBar
,本示例为了简单,就直接使用了TextView,代码如下
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal"
android:background="#cc00cc"
android:gravity="center"
android:paddingTop="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="吃货大赏"
android:textColor="#ffffff"
android:textSize="17sp"
android:padding="10dp"
/>
</LinearLayout>
合二为一
终于到了最后一步,我们需要在设置Activity对系统栏进行设置
首先需要对版本进行一个判定,防止版本不兼容
其次获取DecorView实例
然后使用标志符对系统状态进行设置,其中以下两个系统标志符为全屏和隐藏系统状态栏
重中之重
,以下代码必须在setContentView( R.layout.activity_main );
之前执行
重中之重
,以下代码必须在setContentView( R.layout.activity_main );
之前执行
重中之重
,以下代码必须在setContentView( R.layout.activity_main );
之前执行
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN和View.SYSTEM_UI_FLAG_LAYOUT_STABLE
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE );
getWindow().setStatusBarColor( Color.TRANSPARENT );
}
setContentView( R.layout.activity_main );
InitView();
SelectNumber();
}
Reveal Animator
效果视频
建立一个圆形样式
首先我们需要建立一个圆形样式,在res->drawable下建立一个oval.xml文件
代码如下:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="#cc00cc"/>
</shape>
动画设置
在XML文件中配置我们建立的圆形样式
android:background="@drawable/oval"
然后再Activity中进行动画设置,其中createCircularReveal()
方法的五个参数分别为:控件,动画开始的中心的X,动画开始的中心的Y,动画开始的半径,动画结束的半径
private void RevealAnim(View view) {
Animator animator = ViewAnimationUtils.createCircularReveal(
view, view.getWidth() / 2, view.getHeight() / 2, view.getWidth(), 0
);
animator.setInterpolator( new AccelerateDecelerateInterpolator() );
animator.setDuration( 2000 );
animator.start();
}
自定义转盘代码
public class Turntable extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private SurfaceHolder mSurfaceHolder;
private Canvas mCanvas;
private Thread mThread;
private boolean isRunning;
private String[] itemCharString;
private int[] itemImages;
private Bitmap[] mBitmaps;
private Bitmap mBgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.turntable_bgcolor );
private int[] itemColors;
private int mItemCount = 8;
private RectF mRange = new RectF();
private int mRadius;
private Paint mArcPaint;
private Paint mTextPaint;
private float mTextSize = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
private double mSpeed = 0;
private int mCenter;
private int mPadding;
private volatile float mStartAngle = 0;
private boolean isShouldEnd = false;
private long mOneTimeMinMillionSeconds = 50;
private int mDifferSpeed = 1;// 调用停止后递减的速度差值 要大于0
public Turntable(Context context) {
super(context);
init();
}
public Turntable(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Turntable(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void InitNumber(int number){
if (number <= 0){
return;
}
if (number % 2 == 0){
InitArea(number);
}
}
private void InitArea(int number){
switch (number){
case 4:
fourParts();
break;
case 6:
sixParts();
break;
case 8:
eightParts();
break;
default:
sixParts();
}
}
private void fourParts(){
mItemCount = 4;
itemCharString = new String[]{"粉条", "面条", "米饭", "粥",};
itemImages = new int[]{R.drawable.fen, R.drawable.mian, R.drawable.rice, R.drawable.tang};
itemColors = new int[]{0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01};
InitImage(mItemCount,itemImages);
}
private void sixParts(){
mItemCount = 6;
itemCharString = new String[]{"火锅", "汉堡", "巧克力", "奶茶", "蛋糕", "炸鸡"};
itemImages = new int[]{R.drawable.huoguo, R.drawable.hanbao, R.drawable.qiaokeli, R.drawable.naicha, R.drawable.dangao, R.drawable.zhaji1};
itemColors = new int[]{0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01};
InitImage(mItemCount,itemImages);
}
private void eightParts(){
mItemCount = 8;
itemCharString = new String[]{"苹果", "香蕉", "榴莲", "西瓜", "葡萄", "火龙果","芒果","草莓"};
itemImages = new int[]{R.drawable.apple, R.drawable.xaingjiao, R.drawable.liulian, R.drawable.xigua, R.drawable.putao, R.drawable.huolongguo,R.drawable.mangguo,R.drawable.caomei};
itemColors = new int[]{0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01,0xffffc300,0xfff17e01};
InitImage(mItemCount,itemImages);
}
private void init() {
mSurfaceHolder = this.getHolder();
// 管理SurfaceView的生命周期
mSurfaceHolder.addCallback(this);
// 能够获取焦点
this.setFocusable(true);
this.setFocusableInTouchMode(true);
// 保持常亮
this.setKeepScreenOn(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = Math.min(getMeasuredWidth(), getMeasuredHeight());
mPadding = getPaddingLeft();
mRadius = width - mPadding * 2;
// 中心点
mCenter = width / 2;
setMeasuredDimension(width, width);
}
private void InitImage(int count,int[] item){
mBitmaps = new Bitmap[mItemCount];
for (int i = 0; i < count; i++) {
mBitmaps[i] = BitmapFactory.decodeResource(getResources(), item[i]);
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
// 初始化盘块画笔
mArcPaint = new Paint();
mArcPaint.setAntiAlias(true);
mArcPaint.setDither(true);
// 初始化文字画笔
mTextPaint = new Paint();
mTextPaint.setColor(0xffffffff);
mTextPaint.setTextSize(mTextSize);
// 初始化盘块绘制范围
mRange = new RectF(mPadding, mPadding, mPadding + mRadius, mPadding + mRadius);
// 初始化图片
InitImage(mItemCount,itemImages);
isRunning = true;
mThread = new Thread(this);
mThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
isRunning = false;
}
@Override
public void run() {
while (isRunning) {
long preMillions = System.currentTimeMillis();
draw();
long afterMillions = System.currentTimeMillis();
long drawOnceTime = afterMillions - preMillions;
if (drawOnceTime < mOneTimeMinMillionSeconds) {
try {
Thread.sleep(mOneTimeMinMillionSeconds - drawOnceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void draw() {
try {
mCanvas = mSurfaceHolder.lockCanvas();
if (mCanvas != null) {
drawBgColor();
drawArea();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mCanvas != null) {
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
}
private void drawArea() {
// 起始角度
float tempAngle = mStartAngle;
// 每个盘块绘制的角度
float sweepAngele = 360 / mItemCount;
for (int i = 0; i < mItemCount; i++) {
mArcPaint.setColor(itemColors[i]);
// 绘制盘块
mCanvas.drawArc(mRange, tempAngle, sweepAngele, true, mArcPaint);
// 绘制文本
drawText(tempAngle, sweepAngele, itemCharString[i]);
// 绘制图标
drawIcon(tempAngle, mBitmaps[i]);
tempAngle += sweepAngele;
}
mStartAngle += mSpeed;
// 如果需要停止,让转速逐渐变小直到0
if (isShouldEnd) {
mSpeed -= mDifferSpeed;
}
if (mSpeed <= 0) {
mSpeed = 0;
isShouldEnd = false;
}
}
private void drawIcon(float tempAngle, Bitmap bitmap) {
// 约束图片的宽度,为直径的1/8,可以作为可变参数设置
int imgWidth = mRadius / 8;
// 获取弧度值
float angle = (float) ((tempAngle + 360 / mItemCount / 2) * Math.PI / 180);
// 约定图片位置在直径1/4处
int x = (int) (mCenter + mRadius / 4 * Math.cos(angle));
int y = (int) (mCenter + mRadius / 4 * Math.sin(angle));
// 确定图片位置
Rect rect = new Rect(x - imgWidth / 2, y - imgWidth / 2, x + imgWidth / 2, y + imgWidth / 2);
mCanvas.drawBitmap(bitmap, null, rect, null);
}
private void drawText(float tempAngle, float sweepAngele, String itemTextStr) {
Path path = new Path();
path.addArc(mRange, tempAngle, sweepAngele);
// 利用水平偏移量让文字居中
float textWidth = mTextPaint.measureText(itemTextStr);
int hOffset = (int) (mRadius * Math.PI / mItemCount / 2 - textWidth / 2);
// 利用垂直偏移量让文字向圆心靠拢
int vOffset = mRadius / 2 / 6;
mCanvas.drawTextOnPath(itemTextStr, path, hOffset, vOffset, mTextPaint);
}
private void drawBgColor() {
mCanvas.drawColor(0xFFFFFFFF);
mCanvas.drawBitmap(mBgBitmap, null, new Rect(mPadding / 2, mPadding / 2, getMeasuredWidth() - mPadding / 2, getMeasuredWidth() - mPadding / 2), null);
}
public void Start(int index) {
if (isStart()) {
return;
}
if (index < 0) {
mSpeed = 50 * (1 + Math.random() * (0.5));
isShouldEnd = false;
return;
}
}
public void Stop() {
if (isShouldEnd()) {
return;
}
// 将初始角度重置
mStartAngle = 0;
isShouldEnd = true;
}
public boolean isStart() {
return mSpeed != 0;
}
public boolean isShouldEnd() {
return isShouldEnd;
}
}
XML布局代码
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal"
android:background="#cc00cc"
android:gravity="center"
android:paddingTop="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="吃货大赏"
android:textColor="#ffffff"
android:textSize="17sp"
android:padding="10dp"
/>
</LinearLayout>
<com.franzliszt.foodturntable.Turntable
android:id="@+id/TurnTable"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
android:layout_margin="10dp"
android:layout_centerInParent="true"/>
<ImageView
android:id="@+id/StartAndEnd"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:class="lazy" data-src="@drawable/start"
android:onClick="Start"/>
<com.franzliszt.foodturntable.AnimatedCircleLoadingView
android:id="@+id/loadingView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:alpha="0.9"
android:layout_centerInParent="true"
app:animCircleLoadingView_mainColor="#cc00cc"
app:animCircleLoadingView_secondaryColor="#ff0000"
app:animCircleLoadingView_textColor="@android:color/white"
android:visibility="gone"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/TurnTable"
android:orientation="vertical"
android:layout_marginTop="20dp"
>
<RadioGroup
android:id="@+id/RG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center"
android:gravity="center"
>
<RadioButton
android:id="@+id/fourParts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="主食"
android:layout_marginRight="10dp"
/>
<RadioButton
android:id="@+id/sixParts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="外卖"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"/>
<RadioButton
android:id="@+id/eightParts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="水果"
android:layout_marginLeft="10dp"/>
</RadioGroup>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:layout_marginTop="20dp">
<Button
android:id="@+id/ConfirmSelection"
android:layout_width="40dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
android:background="@drawable/oval"
android:elevation="4dp"
android:onClick="Confirm"
android:text="Confirm"
android:textAllCaps="false"
android:textColor="#ffffff"
android:textSize="12sp" />
<Button
android:elevation="10dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:text="Reset"
android:textSize="12sp"
android:textAllCaps="false"
android:textColor="#ffffff"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:onClick="Reset"
android:background="@drawable/oval"
android:layout_marginLeft="20dp"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Activity代码
public class MainActivity extends AppCompatActivity {
private AnimatedCircleLoadingView loadingView;
private Turntable turntable;
private int count = 0;
private ImageView ChangeStatus;
private RadioGroup RG;
private SP sp;
private Context context = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE );
getWindow().setStatusBarColor( Color.TRANSPARENT );
}
setContentView( R.layout.activity_main );
InitView();
SelectNumber();
}
private void InitView() {
turntable = findViewById( R.id.TurnTable );
loadingView = findViewById( R.id.loadingView );
ChangeStatus = findViewById( R.id.StartAndEnd );
RG = findViewById( R.id.RG );
turntable.InitNumber( 8 );
if (context == null) {
context = MainActivity.this;
}
sp = new SP( context );
}
public void Start(View view) {
count++;
if (count % 2 == 0) {
turntable.Stop();
StartIcon();
} else {
turntable.Start( -1 );
StopIcon();
}
}
private void StartIcon() {
ChangeStatus.setImageDrawable( getResources().getDrawable( R.drawable.start ) );
}
private void StopIcon() {
ChangeStatus.setImageDrawable( getResources().getDrawable( R.drawable.stop ) );
}
public void Confirm(View view) {
RevealAnim( view );
loadingView.setVisibility( View.VISIBLE );
startLoading();
startPercentMockThread();
int num = (int) sp.GetData( context, "num", 0 );
turntable.InitNumber( num );
}
public void Reset(View view) {
RevealAnim( view );
loadingView.setVisibility( View.GONE );
resetLoading();
}
private void startLoading() {
loadingView.startIndeterminate();
}
private void startPercentMockThread() {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
Thread.sleep( 500 );
for (int i = 0; i <= 100; i++) {
Thread.sleep( 40 );
changePercent( i );
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(runnable).start();
}
private void changePercent(final int percent) {
runOnUiThread( new Runnable() {
@Override
public void run() {
loadingView.setPercent( percent );
}
} );
}
public void resetLoading() {
runOnUiThread( new Runnable() {
@Override
public void run() {
loadingView.resetLoading();
}
} );
}
private void RevealAnim(View view) {
Animator animator = ViewAnimationUtils.createCircularReveal(
view, view.getWidth() / 2, view.getHeight() / 2, view.getWidth(), 0
);
animator.setInterpolator( new AccelerateDecelerateInterpolator() );
animator.setDuration( 2000 );
animator.start();
}
private void SelectNumber() {
RG.setOnCheckedChangeListener( new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.fourParts:
sp.PutData( context, "num", 4 );
break;
case R.id.sixParts:
sp.PutData( context, "num", 6 );
break;
case R.id.eightParts:
sp.PutData( context, "num", 8 );
break;
}
}
} );
}
}
代码下载地址
gitee下载地址
到此这篇关于Android 美食大转盘详解流程的文章就介绍到这了,更多相关Android 美食大转盘内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341