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

    xiaoxiao2023-03-24  2

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

    效果图:

    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.布局文件如下:

    <RelativeLayout xmlns:android="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> <ImageButton android:layout_width="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" /> </RelativeLayout>

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

    转载请注明原文地址: https://ju.6miu.com/read-1200134.html
    最新回复(0)