android开发:自定义控件之--抽奖转盘

看网上也有些例子,看着挺有意思。本人之前面试的时候也遇到面试官询问这样的问题,那时候我其实没有清晰的思路,就大体说了下图形绘制过程,需要画笔、画布,设置下各自属性,可以画圆、画弧、画图、画线等。闲话不多说了,直接看看怎么实现的。

效果图:

android开发:自定义控件之--抽奖转盘_第1张图片

1.自定义TurnTableView,继承自View.
初始化的地方,主要是设置了下画笔的属性等。

    // 初始化数据
    private void init(Context context) {
        this.context = context;

        paint = new Paint();
        paint.setColor(Color.RED);// 设置颜色
        paint.setAntiAlias(true);// 去除锯齿效果,会消耗较大资源,绘制图形速度会变慢
        paint.setDither(true);// 防抖动
        paint.setStyle(Paint.Style.STROKE);// 空心
        paint.setStrokeWidth(strokeWidth);// 设置空心边框的宽度
        paint.setAlpha(100);// 透明度
        paint.setARGB(100, 0, 255, 255);// 设置绘制的颜色,a代表透明度,r,g,b代表颜色值。

        textPaint = new Paint();
        textPaint.setColor(Color.RED);// 设置颜色
        textPaint.setTextSize(20);

        // 设置下,对于viewgroup能调用onDraw
        setWillNotDraw(false);
        setKeepScreenOn(true);
    }

2.onMeasure()里拿到测量后的控件的宽高值,取最小值为直径radius,并初始化rangeRectF类对象,这就是个包围圆的一个矩形,用于画弧型和文字。

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        radius = Math.min(getMeasuredWidth(), getMeasuredHeight());
        setMeasuredDimension(radius, radius);
        rangeRectF = new RectF(0, 0, radius, radius);
    }

3.onDraw(Canvas canvas)里绘制圆弧以及文字

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        rotate(canvas);
    }
    float mSpeed = 0;//初始旋转速度(其实也是角度)
    /**
     * 进行旋转
     */
    private void rotate(Canvas canvas) {
        startAngle += mSpeed;
        // 先画几个弧形
        float sweepAngle = 360 / rewards.length;// 每个的弧度
        paint.setStyle(Paint.Style.FILL);
        for (int i = 0; i < rewards.length; i++) {// 子控件
            paint.setColor(colors[i]);
            canvas.drawArc(rangeRectF, startAngle, sweepAngle, true, paint);// 绘制弧形

            float textWidth = textPaint.measureText(rewards[i]); // 获取文字的宽度
            // FontMetrics fontMetrics = textPaint.getFontMetrics();
            // float textHeight = (float) (Math
            // .ceil((fontMetrics.descent - fontMetrics.top)) + 2);

            //水平偏移量: 计算下周长2πr,然后(周长-textWidth)/2
            float hOffset = (float) ((radius * Math.PI / rewards.length - textWidth) / 2);
            //垂直偏移量:半径的1/3
            float vOffset = radius / 2 / 3;
            Path path = new Path();
            path.addArc(rangeRectF, startAngle, sweepAngle);
            canvas.drawTextOnPath(rewards[i], path, hOffset, vOffset, textPaint);// 画文字

            startAngle += sweepAngle;
        }
        if (mSpeed <= 0) {// 要结束了
            isEnd = true;
        }

    }

4.外部调用,旋转操作:


    /**
     * 旋转,其实就是不断重绘,重绘过程中,设置下偏转角度mSpeed,这样就能看出像是转盘在旋转了
     */
    public void start() {
        isEnd = false;
        mSpeed = 5;// 每次旋转的角度
        new Thread(new Runnable() {

            @Override
            public void run() {

                while (!isEnd) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ((MainActivity) context).handler.post(new Runnable() {

                        @Override
                        public void run() {
                            invalidate();
                        }
                    });

                }

            }
        }).start();

        /*
         * 随机数3-6秒之间停止旋转
         */
        double radom = Math.random();
        long time = (long) (radom * 3000 + 3000);
        ((MainActivity) context).handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                end();
            }
        }, time);

    }
    /**
     *  停止旋转
     */
    public void end() {
        isEnd = true;
        // 做一个缓冲效果
        mSpeed = 0;

    }

5.布局文件如下:

"http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".MainActivity" >

    <com.example.turntabledemo.TurnTableView
        android:id="@+id/turn"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_centerHorizontal="true"
        android:layout_margin="10dp" >
    com.example.turntabledemo.TurnTableView>

    "wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="90dp"
        android:background="@null"
        android:onClick="aaa"
        android:src="@drawable/start" />

demo下载:
http://yun.baidu.com/s/1slozw2x

你可能感兴趣的:(android,开发,android开发,控件)