Android 自定义view 小圆绕着大圆转圈

不多说直接上代码。效果图

色值和小球半径在onlayout和Mycircle里慢慢调整,反正是个demo很懒的去重新messure了

 中间球的渐变在ondraw随便搞了个shader


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.tingyutech.moving.rokid.R;

public class CircleLoadingView extends RelativeLayout {
    private static final String TAG = "CircleLoadingView";
    private RotateAnimation rotateAnimation;
    private TextView queue;

    public CircleLoadingView(Context context) {
        super(context);
        init(context);
    }

    public CircleLoadingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CircleLoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        setWillNotDraw(false);
        setGravity(Gravity.CENTER);

        TextView textView = new TextView(context);
        textView.setTextColor(Color.BLACK);
        textView.setTextSize(7);
        textView.setText("当前排在");

        queue = new TextView(context);
        queue.setTextColor(getResources().getColor(R.color.button_loginBlue));
        queue.setText("0位");
        queue.setTextSize(7);

        MyCircle circle = new MyCircle(context);

        rotateAnimation = new RotateAnimation(360, 0);
        rotateAnimation.setRepeatCount(99);
        rotateAnimation.setDuration(3000);
        circle.startAnimation(rotateAnimation);

        addView(textView);
        addView(queue);
        addView(circle);
    }

    public void updateQueue(int position) {
        queue.setText(position + "位");
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int spacing = 30;
        int position = getHeight() / 2 - getChildAt(0).getMeasuredHeight() - spacing;
        for (int i = 0; i < getChildCount(); i++) {
            View view = getChildAt(i);
            position += spacing;
            view.layout(getWidth() / 2 - view.getMeasuredWidth() / 2, position, r, b);
        }

        View c = getChildAt(2);
        c.layout(getWidth() / 2, getHeight() / 2, getWidth(), getHeight() / 2 + 75);
    }

    private int measureWidth(int widthMeasureSpec) {
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);

        int result = 500;
        if (specMode == MeasureSpec.AT_MOST) {   //wrap_content
            // Calculate the ideal size of your
            // control within this maximum size.
            // If your control fills the available
            // space return the outer bound.

            result = specSize;
        } else if (specMode == MeasureSpec.EXACTLY) {  //fill_parent
            // If your control can fit within these bounds return that value.
            result = specSize;
        }
        Log.i(TAG, "measureWidth ----result:" + result);
        // Return measured widget width.
        return result;
    }

    /**
     * 计算控件适合的高度
     *
     * @param heightMeasureSpec
     * @return
     */
    private int measureHeight(int heightMeasureSpec) {
        int specMode = MeasureSpec.getMode(heightMeasureSpec);
        int specSize = MeasureSpec.getSize(heightMeasureSpec);

        int result = 500;
        if (specMode == MeasureSpec.AT_MOST) {
            // Calculate the ideal size of your
            // control within this maximum size.
            // If your control fills the available
            // space return the outer bound.

            result = specSize;
        } else if (specMode == MeasureSpec.EXACTLY) {
            // If your control can fit within these bounds return that value.
            result = specSize;
        }
        Log.i(TAG, "measureHeight --result:" + result);
        // Return measured widget heigth.
        return result;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int measuredHeight = measureHeight(heightMeasureSpec);
        int measuredWidth = measureWidth(widthMeasureSpec);
        setMeasuredDimension(measuredWidth, measuredHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
//        paint.setStyle(Paint.Style.STROKE);
//        paint.setStrokeWidth(10);//描边宽度
        paint.setAntiAlias(true);                       //设置画笔为无锯齿
        paint.setColor(getResources().getColor(R.color.button_loginBlue));

        Shader shader = new RadialGradient(getWidth() / 2, getHeight() / 2, getWidth() / 2 , Color.WHITE, getResources().getColor(R.color.circle_shadow), Shader.TileMode.MIRROR);
        paint.setShader(shader);
        //设置画笔颜色
//        canvas.drawColor(getResources().getColor(R.color.circle_queue_bg));                  //白色背景
        paint.setShadowLayer(5, 0, 0, getResources().getColor(R.color.circle_shadow));

        canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2 - 25, paint);
    }

    // 根据手机的分辨率从 px(像素) 的单位 转成为 dp
    public static int px2dip(Context context, float pxValue) {
        // 获取当前手机的像素密度(1个dp对应几个px)
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f); // 四舍五入取整
    }

    private class MyCircle extends View {
        public MyCircle(Context context) {
            super(context);
        }

        public MyCircle(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }

        public MyCircle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//            setMeasuredDimension(50,50);
        }

        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Paint paint = new Paint();
            paint.setAntiAlias(false);                       //设置画笔为无锯齿
            paint.setColor(getResources().getColor(R.color.button_loginBlue));                    //设置画笔颜色
//            canvas.drawColor(Color.RED);
            canvas.drawCircle(getWidth()-30, 40, 5, paint);
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值