生活随笔
收集整理的這篇文章主要介紹了
Android开发:抽奖转盘的实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
故事的開始
最近有個需求,支付成功的時候加個抽獎輪盤。類似問卷星提交后的那種東西,翻了一下gayhub,下面給出自己的實現思路.
寫在題前
這東西是在github上一個項目是拓展的。但是實現時間和下載項目時間隔了有一陣。所以找不到原鏈沒法掛上,還請見諒。若有知道原鏈的可以在評論區留一下,我后續加上。
效果圖
照例先給最后的實現效果gif圖(轉gif圖的時候應該是抽幀了。實際效果比圖片好一點)
實現思路
1,繪制可以切換背景的獎品View
2,將其排列成九宮格
3,通過前后兩個view的變換,營造出旋轉的感覺
4,狀態標識控制加/減速,直至停止,并發送回調
代碼
PrizeItemView(獎品View)
<?xml version
="1.0" encoding
="utf-8"?>
<FrameLayout xmlns
:android
="http://schemas.android.com/apk/res/android"android
:layout_width
="wrap_content"android
:layout_height
="wrap_content"android
:background
="@drawable/shape_white"><Viewandroid
:id
="@+id/overlay"android
:layout_width
="match_parent"android
:layout_height
="match_parent"android
:background
="@drawable/shape_pink"android
:visibility
="invisible" /><LinearLayoutandroid
:layout_width
="match_parent"android
:layout_height
="match_parent"android
:gravity
="center"android
:orientation
="vertical"><ImageViewandroid
:id
="@+id/iv_prize"android
:layout_width
="60dp"android
:layout_height
="45dp"android
:src
="@drawable/png_prize" /><TextViewandroid
:id
="@+id/tv_prize_name"android
:layout_width
="wrap_content"android
:layout_height
="wrap_content"android
:layout_marginTop
="9dp"android
:text
="一個獎品"android
:textColor
="#98520E"android
:textSize
="22sp" /></LinearLayout>
</FrameLayout>
public class PrizeItemView extends FrameLayout implements PrizeItemApi {private Context mContext
;private View mOverlay
;private ImageView ivPrize
;private TextView tvPrize
;public PrizeItemView(@NonNull Context context
) {this(context
, null);}public PrizeItemView(@NonNull Context context
, @Nullable AttributeSet attrs
) {this(context
, attrs
, 0);}public PrizeItemView(@NonNull Context context
, @Nullable AttributeSet attrs
, int defStyleAttr
) {super(context
, attrs
, defStyleAttr
);inflate(context
, R.layout
.item_prize
, this);mOverlay
= findViewById(R.id
.overlay
);ivPrize
= findViewById(R.id
.iv_prize
);tvPrize
= findViewById(R.id
.tv_prize_name
);mContext
= context
;}@Overridepublic void setFocus(boolean isFocused
) {if (mOverlay
!= null) {mOverlay
.setVisibility(isFocused
? INVISIBLE
: VISIBLE
);}}@Overridepublic void setUi(PrizeListBean bean
) {ivPrize
.setImageResource(bean
.getPrize_path());tvPrize
.setText(bean
.getGoodName());}
}
public interface PrizeItemApi {void setFocus(boolean isFocused
);void setUi(PrizeListBean bean
);
}
這里寫了一個自定義View,實現兩個方法。
1,更新獎品數據修改UI
2,更新獎品選中背景
LuckDrawView(轉盤View)
首先,布局是由8個PrizeItemView拼出來的,哈哈哈哈,中間加個iv,貼了張網上找的開始抽獎
<?xml version
="1.0" encoding
="utf-8"?>
<LinearLayout xmlns
:android
="http://schemas.android.com/apk/res/android"android
:layout_width
="match_parent"android
:layout_height
="match_parent"android
:orientation
="vertical"><LinearLayoutandroid
:layout_width
="match_parent"android
:layout_height
="0dp"android
:layout_marginBottom
="4dp"android
:layout_weight
="1"android
:orientation
="horizontal"><com.huahen.luckdraw.luckDrawView.PrizeItemViewandroid
:id
="@+id/item1"android
:layout_width
="0dp"android
:layout_height
="match_parent"android
:layout_marginRight
="8dp"android
:layout_weight
="1" /><com.huahen.luckdraw.luckDrawView.PrizeItemViewandroid
:id
="@+id/item2"android
:layout_width
="0dp"android
:layout_height
="match_parent"android
:layout_marginRight
="8dp"android
:layout_weight
="1" /><com.huahen.luckdraw.luckDrawView.PrizeItemViewandroid
:id
="@+id/item3"android
:layout_width
="0dp"android
:layout_height
="match_parent"android
:layout_marginRight
="8dp"android
:layout_weight
="1" /></LinearLayout><LinearLayoutandroid
:layout_width
="match_parent"android
:layout_height
="0dp"android
:layout_marginBottom
="8dp"android
:layout_weight
="1"android
:orientation
="horizontal"><com.huahen.luckdraw.luckDrawView.PrizeItemViewandroid
:id
="@+id/item8"android
:layout_width
="0dp"android
:layout_height
="match_parent"android
:layout_marginRight
="8dp"android
:layout_weight
="1" /><ImageViewandroid
:id
="@+id/iv_start"android
:layout_width
="0dp"android
:layout_height
="match_parent"android
:layout_marginRight
="8dp"android
:layout_weight
="1"android
:background
="@drawable/luck_draw_btn" /><com.huahen.luckdraw.luckDrawView.PrizeItemViewandroid
:id
="@+id/item4"android
:layout_width
="0dp"android
:layout_height
="match_parent"android
:layout_marginRight
="8dp"android
:layout_weight
="1" /></LinearLayout><LinearLayoutandroid
:layout_width
="match_parent"android
:layout_height
="0dp"android
:layout_marginBottom
="8dp"android
:layout_weight
="1"android
:orientation
="horizontal"><com.huahen.luckdraw.luckDrawView.PrizeItemViewandroid
:id
="@+id/item7"android
:layout_width
="0dp"android
:layout_height
="match_parent"android
:layout_marginRight
="8dp"android
:layout_weight
="1" /><com.huahen.luckdraw.luckDrawView.PrizeItemViewandroid
:id
="@+id/item6"android
:layout_width
="0dp"android
:layout_height
="match_parent"android
:layout_marginRight
="8dp"android
:layout_weight
="1" /><com.huahen.luckdraw.luckDrawView.PrizeItemViewandroid
:id
="@+id/item5"android
:layout_width
="0dp"android
:layout_height
="match_parent"android
:layout_marginRight
="8dp"android
:layout_weight
="1" /></LinearLayout></LinearLayout>
顯示是這樣的
來了。全文最主要的代碼
public class LuckDrawView extends FrameLayout {private PrizeItemView itemView1
, itemView2
, itemView3
,itemView8
, itemView4
,itemView7
, itemView6
, itemView5
;private ImageView ivStart
;private OnItemListener listener
;private PrizeItemApi[] itemViewArr
= new PrizeItemApi[8];private int currentIndex
= 0;private int currentTotal
= 0;private int stayIndex
= 0;private boolean isMarqueeRunning
= false;private boolean isGameRunning
= false; private boolean isTryToStop
= false;private static final int DEFAULT_SPEED
= 150; private static final int MIN_SPEED
= 50;private int currentSpeed
= DEFAULT_SPEED
;Timer timer
= new Timer();public LuckDrawView(@NonNull Context context
) {this(context
, null);}public LuckDrawView(@NonNull Context context
, @Nullable AttributeSet attrs
) {this(context
, attrs
, 0);}public LuckDrawView(@NonNull Context context
, @Nullable AttributeSet attrs
, int defStyleAttr
) {super(context
, attrs
, defStyleAttr
);inflate(context
, R.layout
.view_luck_draw_nine
, this);initView();}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();startMarquee();}@Overrideprotected void onDetachedFromWindow() {stopMarquee();super.onDetachedFromWindow();}private void initView() {itemView1
= (PrizeItemView) findViewById(R.id
.item1
);itemView2
= (PrizeItemView) findViewById(R.id
.item2
);itemView3
= (PrizeItemView) findViewById(R.id
.item3
);itemView4
= (PrizeItemView) findViewById(R.id
.item4
);itemView5
= (PrizeItemView) findViewById(R.id
.item5
);itemView6
= (PrizeItemView) findViewById(R.id
.item6
);itemView7
= (PrizeItemView) findViewById(R.id
.item7
);itemView8
= (PrizeItemView) findViewById(R.id
.item8
);itemViewArr
[0] = itemView1
;itemViewArr
[1] = itemView2
;itemViewArr
[2] = itemView3
;itemViewArr
[3] = itemView4
;itemViewArr
[4] = itemView5
;itemViewArr
[5] = itemView6
;itemViewArr
[6] = itemView7
;itemViewArr
[7] = itemView8
;ivStart
= findViewById(R.id
.iv_start
);ivStart
.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v
) {listener
.onClick();}});}private void stopMarquee() {isMarqueeRunning
= false;isGameRunning
= false;isTryToStop
= false;}private void startMarquee() {isMarqueeRunning
= true;new Thread(new Runnable() {@Overridepublic void run() {while (isMarqueeRunning
) {try {Thread.sleep(500);} catch (InterruptedException e
) {e
.printStackTrace();}
}}}).start();}private long getInterruptTime() {currentTotal
++;if (isTryToStop
) {currentSpeed
+= 10;if (currentSpeed
> DEFAULT_SPEED
) {currentSpeed
= DEFAULT_SPEED
;}} else {if (currentTotal
/ itemViewArr
.length
> 0) {currentSpeed
-= 10;}if (currentSpeed
< MIN_SPEED
) {currentSpeed
= MIN_SPEED
;}}return currentSpeed
;}public boolean isGameRunning() {return isGameRunning
;}public void startGame(final int stayIndex
) {if (isGameRunning
) {return;}isGameRunning
= true;isTryToStop
= false;currentSpeed
= DEFAULT_SPEED
;new Thread(new Runnable() {@Overridepublic void run() {while (isGameRunning
) {try {Thread.sleep(getInterruptTime());} catch (InterruptedException e
) {e
.printStackTrace();}post(new Runnable() {@Overridepublic void run() {if (!isGameRunning
) {return;}int preIndex
= currentIndex
;currentIndex
++;if (currentIndex
>= itemViewArr
.length
) {currentIndex
= 0;}itemViewArr
[preIndex
].setFocus(true);itemViewArr
[currentIndex
].setFocus(false);if (isTryToStop
&& currentSpeed
== DEFAULT_SPEED
&& stayIndex
== currentIndex
) {isGameRunning
= false;listener
.onShop(currentIndex
);}}});}}}).start();timer
.schedule(new TimerTask() {@Overridepublic void run() {tryToStop();}}, 5000);}public void tryToStop() {isTryToStop
= true;}public void setData(List<PrizeListBean> beans
) {if (beans
!= null) {for (int i
= 0; i
< beans
.size(); i
++) {itemViewArr
[i
].setUi(beans
.get(i
));}}}public void setOnItemListener(OnItemListener listener
) {this.listener
= listener
;}public interface OnItemListener {void onClick();void onShop(int Index);}
}
這么清晰的注釋,應該不用我怎么解釋了吧
最后是調用
mLuckDrawView
= findViewById(R.id
.luck_draw
);mLuckDrawView
.setOnItemListener(new LuckDrawView.OnItemListener() {@Overridepublic void onClick() {int stayIndex
= new Random().nextInt(8);mLuckDrawView
.startGame(stayIndex
);}@Overridepublic void onShop(int Index) {Toast.makeText(MainActivity.this, "這是第" + Index + "個商品", Toast.LENGTH_SHORT
).show();}});mLuckDrawView
.setData(getLuckDrawData());
就這樣,一個抽獎轉盤就這么實現
可能不盡完美,但也是我提供的一種思路吧。。也歡迎大家一起討論。
筆者寫到這里也不容易,如果這篇文章有幫助到你。冒昧地請求兄弟點個贊唄,如果有不同的見解。也歡迎在評論區一起探討
總結
以上是生活随笔為你收集整理的Android开发:抽奖转盘的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。