使用RecyclerView实现抽奖

使用RecyclerView实现抽奖

        

        看到这福抽奖图片,大家可以考虑下如何实现?自定义控件,自己绘制?在这里我们我们有更简单的方法,使用3个RecyclerView进行实现。为了实现抽奖,我们会遇到如下2个问题。源码:https://github.com/zhao007z4/jackpot

        1、如何控制3个RecyclerView的速度,使得他们在不同的时间停止?

        2、如何控制每列值显示,显示的项目个数?

        3、从服务器拉取到结果后,如果让RecyclerView,滚动到指定的项目?

        带着以上问题,我们来一一实现

一、如何控制3个RecyclerView的速度,使得他们在不同的时间停止?

    RecyclerView,自带神器,可以通过自定义LinearLayoutManager实现对滚动速度的控制。代码如下
   
  1. public class FastScrollLinearLayoutManager extends LinearLayoutManager {
  2. public FastScrollLinearLayoutManager(Context context) {
  3. super(context);
  4. }
  5. @Override
  6. public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
  7. LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
  8. @Override
  9. public PointF computeScrollVectorForPosition(int targetPosition) {
  10. return FastScrollLinearLayoutManager.this.computeScrollVectorForPosition(targetPosition);
  11. }
  12. //该方法控制速度。
  13. //if returned value is 2 ms, it means scrolling 1000 pixels with LinearInterpolation should take 2 seconds.
  14. @Override
  15. protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
  16. /*
  17. 控制单位速度, 毫秒/像素, 滑动1像素需要多少毫秒.
  18. 默认为 (25F/densityDpi) 毫秒/像素
  19. mdpi上, 1英寸有160个像素点, 25/160,
  20. xxhdpi,1英寸有480个像素点, 25/480,
  21. */
  22. //return 10F / displayMetrics.densityDpi;//可以减少时间,默认25F
  23. return super.calculateSpeedPerPixel(displayMetrics);
  24. }
  25. //该方法计算滑动所需时间。在此处间接控制速度。
  26. //Calculates the time it should take to scroll the given distance (in pixels)
  27. @Override
  28. protected int calculateTimeForScrolling(int dx) {
  29. /*
  30. 控制距离, 然后根据上面那个方(calculateSpeedPerPixel())提供的速度算出时间,
  31. 默认一次 滚动 TARGET_SEEK_SCROLL_DISTANCE_PX = 10000个像素,
  32. 在此处可以减少该值来达到减少滚动时间的目的.
  33. */
  34. //间接计算时提高速度,也可以直接在calculateSpeedPerPixel提高
  35. if (dx > 3000) {
  36. dx = 3000;
  37. }
  38. int time = super.calculateTimeForScrolling(dx);
  39. LogUtil.d(time);//打印时间看下
  40. return time;
  41. }
  42. };
  43. linearSmoothScroller.setTargetPosition(position);
  44. startSmoothScroll(linearSmoothScroller);
  45. }
  46. }

二、如何控制每列中,显示的项目个数

    通过之定义ImageView,在onMeasure中控制每个项目大小。每个项目的大小,可以通过RecyclerView高度所占比例/3进行计算,以下代码以背景图1080X1920为基准,RecyclerView高度占比630    

@Override
  1. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
  2. {
  3. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  4. DisplayMetrics dm = getResources().getDisplayMetrics();
  5. int iWidth = (dm.heightPixels*630)/(1920*3);
  6. int iNewWidth = dm.widthPixels*254/1080;
  7. iWidth = iWidth>iNewWidth?iNewWidth:iWidth;
  8. setMeasuredDimension(iWidth, iWidth);
  9. }

 三、从服务器拉取到结果后,如果让RecyclerView,滚动到指定的项目?

        当开始转动时,我们不知道应用到底需要转动到那个项,这个时候我们设置指定项为MAX_VAULE,
让其一直循环转动。
    recycler1.smoothScrollToPosition(Integer.MAX_VALUE);
    recycler2.smoothScrollToPosition(Integer.MAX_VALUE);
    recycler3.smoothScrollToPosition(Integer.MAX_VALUE);
   当应用获取到服务器给的抽奖结果时,根据抽奖结果,可以计算出每个Recycler应该停止的项目。有了停止项,在获取
每个Recycler的当前项。最后计算出还需要滚动的项,代码如下
  1. private void dealSpinAndWin(JackpotResult winRetInfo)
  2. {
  3. int iCount = JackpotAdapter.getProductCount();
  4. int pos1 = scrollSpeedLinearLayoutManger[0].findFirstVisibleItemPosition();
  5. int pos2 = scrollSpeedLinearLayoutManger[1].findFirstVisibleItemPosition();
  6. int pos3 = scrollSpeedLinearLayoutManger[2].findFirstVisibleItemPosition();
  7. if(pos2<iCount)
  8. {
  9. handler.sendEmptyMessageDelayed(MSG_CODE_WIN,500);
  10. return;
  11. }
  12. int index = 0;
  13. if(winRetInfo==null)
  14. {
  15. bSucc = false;
  16. index = Rnd(0,iCount);
  17. }
  18. else
  19. {
  20. bSucc = true;
  21. index = getIndex(winRetInfo);
  22. }
  23. int newpos1 = scrollSpeedLinearLayoutManger[0].findFirstVisibleItemPosition() % iCount;
  24. int newpos2 = scrollSpeedLinearLayoutManger[1].findFirstVisibleItemPosition() % iCount;
  25. int newpos3 = scrollSpeedLinearLayoutManger[2].findFirstVisibleItemPosition() % iCount;
  26. if (newpos1 > index) {
  27. newpos1 = pos1 - (newpos1 - index);
  28. } else {
  29. newpos1 = pos1 - (iCount + (newpos1 - index));
  30. }
  31. if (newpos3 > index) {
  32. newpos3 = pos3 - (newpos3 - index);
  33. } else {
  34. newpos3 = pos3 - (iCount + (newpos3 - index));
  35. }
  36. if (bSucc) {
  37. if (newpos2 > index) {
  38. newpos2 = pos2 - (newpos2 - index);
  39. } else {
  40. newpos2 = pos2 - (iCount + (newpos2 - index));
  41. }
  42. } else {
  43. if (newpos2 > index) {
  44. newpos2 = pos2 - (newpos2 - index) - 1;
  45. } else {
  46. newpos2 = pos2 - (iCount + (newpos2 - index)) + 1;
  47. }
  48. }
  49. recycler1.smoothScrollToPosition(newpos1 - 1);
  50. recycler2.smoothScrollToPosition(newpos2 - 1);
  51. recycler3.smoothScrollToPosition(newpos3 - 1);
  52. }

    看完之后,大家应该基本了解了,如果做抽奖了。这里不多说了。如果大家敢兴趣,可以下载源码试试:

https://github.com/zhao007z4/jackpot

    最后,还要唠叨下如果需要适配android4.4,RecylerView最好自定义固定大小,这样可以避免在android4.4中重复计算子项,导致死机。

阅读更多
个人分类: android
上一篇复杂背景图,如何布局
下一篇android 查看UID
想对作者说点什么? 我来说一句

利用Qt开发的抽奖小程序

2016年09月20日 11.85MB 下载

Js抽奖代码,转盘抽奖

2016年04月28日 93KB 下载

没有更多推荐了,返回首页

关闭
关闭