android自定義view--抽獎轉盤 指定中獎位置

不知不覺已經出來工作了7個月,今天剛剛好轉正一個月了,花了1個多月的時間,在公司完成了android集成RN的項目。做的時候真的遇到好多坑,還好都一一解決了。O(∩_∩)O哈哈~,做完這個項目又閑下來的。好想有項目迭代!!!

效果圖--錄屏軟件錄的有點差

test2.gif

實現步驟---思路

  • 設置轉盤的寬高
  • 繪制圓形背景
  • 繪制轉盤
  • 繪制轉盤上的文字和圖片
  • 轉盤的旋轉動畫以及監聽
  • 指定旋轉的位置

在onMeasure上設置轉盤的寬高---我在布局中設置了padding=30dp

   @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int w = MeasureSpec.getSize(widthMeasureSpec);
        int h = MeasureSpec.getSize(heightMeasureSpec);

        int width = Math.min(w, h);
        //圓心點
        mCenter = width / 2;
        //半徑
        mRadius = (width - getPaddingLeft() * 2) / 2;

        //設置框高都一樣
        setMeasuredDimension(width, width);
    }

繪制圓形背景--- canvas.drawCircle(cx,cy,radius,paint);

        canvas.drawCircle(mCenter, mCenter, mCenter - getPaddingLeft() / 2, mBgPaint);

繪制轉盤

       //設置扇形繪制的范圍
        sectorRectF = new RectF(getPaddingLeft(), getPaddingLeft(),
                mCenter * 2 - getPaddingLeft(), mCenter * 2 - getPaddingLeft());
    for (int i = 0; i < mCount; i++) {
            //扇形的顏色
            mArcPaint.setColor(sectorColor[i % 2]);
            //sectorRectF 扇形繪制范圍  startAngle 弧開始繪制角度       
            //sweepAngle 每次繪制弧的角度 
            // useCenter 是否連接圓心 
            canvas.drawArc(sectorRectF, startAngle, sweepAngle, true, mArcPaint);
            startAngle += sweepAngle;
        }

看看效果了---背景原的半徑比轉盤的半徑多了paddingleft()/2

image.png

繪制轉盤上的文字需要使用到的方法
path.addArc--------添加圓弧路徑
canvas.drawTextOnPath------根據路徑繪制文字

 private void drawTexts(Canvas canvas, String mString) {
        Path path = new Path();
        //添加一個圓弧的路徑
        path.addArc(sectorRectF, startAngle, sweepAngle);
        String startText = null;
        String endText = null;
        //測量文字的寬度
        float textWidth = mTextPaint.measureText(mString);
        //水平偏移
        int hOffset = (int) (mRadius * 2 * Math.PI / mCount / 2 - textWidth / 2);
        //計算弧長 處理文字過長換行
        int l = (int) ((360 / mCount) * Math.PI * mRadius / 180);
        if (textWidth > l * 4 / 5) {
            int index = mString.length() / 2;
            startText = mString.substring(0, index);
            endText = mString.substring(index, mString.length());

            float startTextWidth = mTextPaint.measureText(startText);
            float endTextWidth = mTextPaint.measureText(endText);
            //水平偏移
            hOffset = (int) (mRadius * 2 * Math.PI / mCount / 2 - startTextWidth / 2);
            int endHOffset = (int) (mRadius * 2 * Math.PI / mCount / 2 - endTextWidth / 2);
            //文字高度
            int h = (int) ((mTextPaint.ascent() + mTextPaint.descent()) * 1.5);

            //根據路徑繪制文字
            canvas.drawTextOnPath(startText, path, hOffset, mRadius / 6, mTextPaint);
            canvas.drawTextOnPath(endText, path, endHOffset, mRadius / 6 - h, mTextPaint);
        } else {
            //根據路徑繪制文字
            canvas.drawTextOnPath(mString, path, hOffset, mRadius / 6, mTextPaint);
        }
    }

弧長公式 length=圓心角度數xMath.PIx半徑/180 計算到弧長之后根據的需要修改

繪制轉盤上的圖片

image.png

求出x,y的坐標 利用三角函數
y=sin(角度)×raduis/2+mCenter
x=cos(角度)×raduis/2+mCenter

private void drawIcons(Canvas canvas, Bitmap mBitmap) {
        int imageWidth = mRadius / 10;
        //計算半邊扇形的角度 度=Math.PI/180 弧度=180/Math.PI
        float angle = (float) ((startAngle + sweepAngle / 2) * Math.PI / 180);
        //計算中心點的坐標
        int r = mRadius / 2;
        float x = (float) (mCenter + r * Math.cos(angle));
        float y = (float) (mCenter + r * Math.sin(angle));
        //設置繪制圖片的范圍
        RectF rectF = new RectF(x - imageWidth, y - imageWidth, x + imageWidth, y + imageWidth);
        canvas.drawBitmap(mBitmap, null, rectF, null);
    }

轉盤的旋轉動畫監聽以及指定旋轉的位置

先看個圖片canvas.drawArc()繪制的開始點


image.png

canvas.drawArc() 在右邊x軸正方向開始繪制

image.png

指針指向的方向是270度,旋轉方向為順時針,現在這里有10個扇形就是每個占了36°,當旋轉了36°,指針指向的是黃忠。我這里寫以尷尬差點中獎為第0個元素,那么第1個元素就是元歌,如果我想要元歌的英雄旋轉的度數就是369,公式:360/個數×(個數-位置)*

image.png

怎么獲取到旋轉的信息呢?
使用:Arrays.binarySearch()

 public void rotate(final int i) {

        rotateToPosition = 360 / mCount * (mCount - i);
        float toDegree = 360f * 5 + rotateToPosition;

        animator = ObjectAnimator.ofFloat(PieView.this, "rotation", 0, toDegree);
        animator.setDuration(5000);
        animator.setRepeatCount(0);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.setAutoCancel(true);
        animator.start();

        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                //指針指向的方向為270度
                if (listener != null) {
                    rotateToPosition = 270 - rotateToPosition;
                    if (rotateToPosition < 0) {
                        rotateToPosition += 360;
                    } else if (rotateToPosition == 0) {
                        rotateToPosition = 270;
                    }
                    position = -Arrays.binarySearch(angles, rotateToPosition) - 1;
                    listener.value(mStrings[position - 1]);
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {


            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
    }

源碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容