美文网首页api 架构
Android 9宫格抽奖 不是类似PPT那种样子

Android 9宫格抽奖 不是类似PPT那种样子

作者: 一个冬季 | 来源:发表于2019-12-20 23:38 被阅读0次
参考文献

Android超简单实现九宫格抽奖

抽奖.gif
代码

9宫格抽奖Demo

需求描述

需要做一个抽奖的效果,网上搜索了一下,发现没有搜索到那个可以移动的正方形的圈圈,只是搜索到了修改每个圈圈的颜色的这种的,上面的那一篇博客写的很好,给了我很大的思路。我这个是另外的一个思路

让人感觉的头痛点

1、计算每个正方形的位置
2、如何完美的移动到我需要的位置

设计思路
布局方向.jpg

这些数字都是中奖View的位置。现在如何让移动的框框,正好的框在每一个View上面?如下面展示的,我红色的框框是一个透明的FrameLayout,它的作用就是保证包裹每一个黑色的框,且是要是剧中的。蓝色是一张图片,在FrameLayout里面,且是剧中显示的,当然蓝色的宽高要 > 黑色的宽高,黑色的框框0....11表示的是每个中奖的View。所以我们每次都TransLayoutX/Y红色的框框就OK啦


布局解释图.jpg
画出12个中奖View代码
   /**
     * @date :2019/12/17 0017
     * @author : gaoxiaoxiong
     * @description:创建12个Viwe视图
     **/
    private View createView(int position) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.view_child_tweleveluck, this, false);
        LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        view.setLayoutParams(layoutParams);
        view.setBackgroundColor(ContextCompat.getColor(mContext, R.color.white));
        ImageView imageView = view.findViewById(R.id.iv_view_child_tweleveluck);
        imageView.setImageResource(mImgs[position % 3]);
        return view;
    }

    /**
     * @date :2019/12/20 0020
     * @author : gaoxiaoxiong
     * @description:创建12个Viwe视图
     **/
    public void updateView() {
        removeAllViews();
        for (int i = 0; i < 12; i++) {
            viewList.add(createView(i));
            addView(viewList.get(i));
        }
    }

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mRectParentWidth = getMeasuredWidth();
        itemWidthHeight = (mRectParentWidth - itemSpace * 5) / 4;
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = viewList.get(i);
            LayoutParams layoutParams = view.getLayoutParams();
            layoutParams.width = itemWidthHeight;
            layoutParams.height = itemWidthHeight;
            view.setLayoutParams(layoutParams);
            measureChild(view, widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //前3个
        int left = 0, top = 0, right = 0, bottom = 0;
        top = itemSpace;
        left = itemSpace;
        for (int i = 0; i < 3; i++) {
            View view = viewList.get(i);
            view.layout(left, top, left + itemWidthHeight, top + itemWidthHeight);
            left = left + itemWidthHeight + itemSpace;
        }

        //右边4个
        left = 3 * (itemWidthHeight + itemSpace) + itemSpace;
        top = itemSpace;
        bottom = itemSpace + itemWidthHeight;
        for (int i = 3; i < 7; i++) {
            right = left + itemWidthHeight;
            View view = viewList.get(i);
            view.layout(left, top, right, bottom);
            top = top + itemWidthHeight + itemSpace;
            bottom = bottom + itemSpace + itemWidthHeight;
        }

        //底部3个
        top = (itemSpace + itemWidthHeight) * 3 + itemSpace;
        bottom = top + itemWidthHeight;
        left = (itemSpace + itemWidthHeight) * 2 + itemSpace;
        right = left + itemWidthHeight;
        for (int i = 7; i < 10; i++) {
            View view = viewList.get(i);
            view.layout(left, top , right, bottom);
            left = left - (itemSpace + itemWidthHeight);
            right = left + itemWidthHeight;
        }
        //左边2个
        left = itemSpace;
        right = itemSpace + itemWidthHeight;
        top = 2 * (itemWidthHeight + itemSpace) + itemSpace;
        bottom = top + itemWidthHeight;
        for (int i = 10; i < 12; i++) {
            View view = viewList.get(i);
            view.layout(left , top , right, bottom);
            top = top - (itemWidthHeight + itemSpace);
            bottom = top + itemWidthHeight;
        }
    }
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/shape_rectangle_solid_white_corner5">
    <ImageView
        android:id="@+id/iv_view_child_tweleveluck"
        android:layout_width="match_parent"
        android:layout_gravity="center"
        android:layout_height="match_parent" />
</FrameLayout>

因为我们中奖的View都是通过LayoutInflater.from(mContext).inflate出来的,所以我们可以保证这个View里面的图片一定是剧中的,如上面的GIF里面的白菜/龙虾,而且我们还可以设置View的背景 + 是否圆角等等。

移动红色的框框到指定的位置
<FrameLayout
        android:layout_width="314dp"
        android:layout_height="314dp"
        android:layout_gravity="center"
        android:background="@drawable/shape_rectangle_solid_white_corner5">
        <!--12个View的父容器-->
        <com.example.myapplication.TwelveLuckPanLayoutV2
            android:id="@+id/luck_drawa_twelevluck"
            android:layout_width="308dp"
            android:layout_height="308dp"
            android:layout_gravity="center"
            android:background="@color/liba_720f1b" />
        <!--开始按钮-->
        <ImageView
            android:id="@+id/luck_drawa_startchou"
            android:layout_width="140dp"
            android:layout_height="140dp"
            android:layout_gravity="center"
            android:src="@drawable/icon_go" />
        <!--和TwelveLuckPanLayoutV2宽高大小保持一致,为了后面计算方便-->
        <FrameLayout
            android:layout_width="308dp"
            android:layout_height="308dp"
            android:layout_gravity="center">
            <!--红色的FrameLayout-->
            <FrameLayout
                android:id="@+id/fl_luck_drawa_work_kuang"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
                <!--蓝色的ImageView-->
                <ImageView
                    android:id="@+id/iv_luck_drawa_work_kuang"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:scaleType="fitXY"
                    android:src="@mipmap/icon_work_kuang" />
            </FrameLayout>
        </FrameLayout>
    </FrameLayout>

这里要特别注意的有2点
1、有2个View都是308dp的宽高,都是在父容器里面剧中的,还有就是是为了保证在计算移动红色FrameLayout的时候减少错误
2、红色的FrameLayout包裹着一个ImageView且是剧中的模式

/**
    * @date: 创建时间:2019/12/20
    * @author: gaoxiaoxiong
    * @descripion:需要中奖的View
    **/
    public void onPosition(final int position) {
       final int totalWidth = twelveLuckPanLayout.getmRectParentWidth() - twelveLuckPanLayout.getmRectParentWidth() / 4;//一条直线上的
       final int oneItem = twelveLuckPanLayout.getmRectParentWidth() / 4;//一个的Item
       final   ValueAnimator valueAnimator = ValueAnimator.ofInt(0, oneItem * 12);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int currentValue = (int) animation.getAnimatedValue();
                float percent = (float) currentValue / ((float) totalWidth * 4);
                if (currentValue >= 0 && currentValue <= totalWidth) {//第一排
                    flWorkKuangLayout.setTranslationX(percent * totalWidth * 4);
                    flWorkKuangLayout.setTranslationY(0);
                } else if (currentValue > totalWidth && currentValue <= totalWidth * 2) {//第二
                    flWorkKuangLayout.setTranslationX(twelveLuckPanLayout.getmRectParentWidth() - flWorkKuangLayout.getWidth());
                    float release = percent * totalWidth * 4 - totalWidth;
                    flWorkKuangLayout.setTranslationY(release);
                } else if (currentValue > totalWidth * 2 && currentValue <= totalWidth * 3) {//第三
                    flWorkKuangLayout.setTranslationY(totalWidth);
                    float release = percent * totalWidth * 4 - totalWidth * 3;
                    flWorkKuangLayout.setTranslationX(-release);
                } else if (currentValue > totalWidth * 3 && currentValue <= totalWidth * 4) {//第四
                    float release = percent * totalWidth * 4 - totalWidth * 4;
                    flWorkKuangLayout.setTranslationY(-release);
                    flWorkKuangLayout.setTranslationX(0);
                }
                if (currentValue == totalWidth * 4) {
                    flWorkKuangLayout.setTranslationY(0);
                    flWorkKuangLayout.setTranslationX(0);
                }

                if (repecount == 2 && !isSetting) {
                    int trans = oneItem * position;
                    valueAnimator.setIntValues(trans);
                    isSetting = true;
                }
            }
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                int trans = oneItem * position;
                if (trans >= 0 && trans <= totalWidth) {//第一排
                    flWorkKuangLayout.setTranslationX(twelveLuckPanLayout.getChildAt(position).getLeft() - twelveLuckPanLayout.getItemSpace());
                } else if (trans > totalWidth && trans <= totalWidth * 2) {//第二
                    flWorkKuangLayout.setTranslationY(twelveLuckPanLayout.getChildAt(position).getTop() - twelveLuckPanLayout.getItemSpace());
                } else if (trans > totalWidth * 2 && trans <= totalWidth * 3) {//第三
                    flWorkKuangLayout.setTranslationY(twelveLuckPanLayout.getChildAt(position).getTop() - twelveLuckPanLayout.getItemSpace());
                    flWorkKuangLayout.setTranslationX(twelveLuckPanLayout.getChildAt(position).getLeft() - twelveLuckPanLayout.getItemSpace());
                } else if (trans > totalWidth * 3 && trans <= totalWidth * 4) {//第四
                    flWorkKuangLayout.setTranslationY(twelveLuckPanLayout.getChildAt(position).getTop() - twelveLuckPanLayout.getItemSpace());
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                repecount = repecount + 1;
                flWorkKuangLayout.setTranslationY(0);
                flWorkKuangLayout.setTranslationX(0);
            }
        });
        valueAnimator.setRepeatCount(2);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setDuration(1000);
        valueAnimator.start();
    }

我们红色框框转一圈所需要移动的距离是12 * oneItem ,在这里我们先让他故意转2圈,当到了第二圈的时候我们通过

           if (repecount == 2 && !isSetting) {
                    int trans = oneItem * position;
                    valueAnimator.setIntValues(trans);
                    isSetting = true;
                }

来锁定最后他移动到的位置,我们每次移动都是移动整个红色的框框
totalWidth:我们从 0 位置 移动到 3位置,我们实际移动的是3个item的宽度,所以这里表示的是我们每一边最多移动多少距离

相关文章

  • Android 9宫格抽奖 不是类似PPT那种样子

    参考文献 Android超简单实现九宫格抽奖 代码 9宫格抽奖Demo 需求描述 需要做一个抽奖的效果,网上搜索了...

  • react-native FlatList实现GridView效

    做Android的人都知道,Android有一种控件叫GridView,可以用来展示图片,类似于9宫格效果,而在r...

  • Android开发12宫格抽奖

    一、效果图 二、关键代码 NineLuckPan 并非全部原创,是在网上找到的九宫格进行修改的。 如有需要完整de...

  • AutoLayout分分钟搞定等比例布局

    9宫格布局 有时候开发中会碰到9宫格布局 注意不是collectionView 或者tableView 的数据...

  • JavaScript 实现九宫格抽奖

    九格宫抽奖相信大家都玩过,今天就用 JavaScript 写个九宫格抽奖玩玩。让中奖不再是梦! 1.预览效果 效果...

  • 宫格抽奖思路

    实现一个4*4d的宫格抽奖 第一步:UI实现正方形,可以循环渲染然后掏空中间部分,每个方格设置data-set第二...

  • 九宫格排列

    常见类似九宫格排列 源码下载地址:http://download.csdn.net/detail/rwz_my/9...

  • mpvue封装九宫格抽奖组件

    最近用mpvue做小程序,有一个需求是做九宫格抽奖。因此参考了一篇文章从而封装了一个九宫格抽奖组件,可以直接拿来用...

  • 布局小技巧

    GridView 里面 九宫格,纵向的item每个宫格居中 =GridView里面 android:gravity...

  • Android九宫格控件-可在ListView和Recycler

    需求场景 熟悉Android App开发的同学,肯定都清楚,如果要显示多张图片,类似九宫格,可以用GridView...

网友评论

    本文标题:Android 9宫格抽奖 不是类似PPT那种样子

    本文链接:https://www.haomeiwen.com/subject/bbfinctx.html