PanePicView输入一个值使指针旋转一个角度

本文介绍了一个自定义的Android视图组件PanePicView,该组件可以显示一个带有指针的圆形进度条,并通过SeekBar传入值来更新指针位置。文章详细展示了组件的创建过程,包括XML属性设置、测量和绘制逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<declare-styleable name="PanePicView">
<attr name="maxValue" format="integer"/>
</declare-styleable>

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.MeasureSpec;

public class PanePicView extends View {
	
	private int mStartAngle = 180;
    private int DURING_ARC = 180;
    private int mMinValue = 0; // 最小值
    private int mMaxValue = 200; // 最大值
	public PanePicView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PanePicView, defStyleAttr, 0);
		mMaxValue = a.getInteger(R.styleable.PanePicView_maxValue, 200);
		init();
	}

	public PanePicView(Context context, AttributeSet attrs) {
		this(context, attrs,0);
	}

	public PanePicView(Context context) {
		this(context,null);
	}
	private Paint mPaint;
	private Path mPath;
	private Rect mRect;
	private void init(){
		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setDither(true);
		mPath = new Path();
		mRect = new Rect();
	}
	private int mViewWidth; // 控件宽度
    private int mViewHeight; // 控件高度
    private float mCenterX;
    private float mCenterY;
    private int mPercent; //seekBar传入的值
    private int innerRadios = 30;
    private int pointRadios = 4;
    private int pointLenght = 30;
    private int pointRadiosOfset = 2;//指针小圆偏移量
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            mViewWidth = widthSize;
        } else {
        	mViewWidth = 204;
        }
        if (heightMode == MeasureSpec.EXACTLY) {
            mViewHeight = heightSize;
        } else {
        	mViewHeight = 134;
        }
        mCenterX = mViewWidth/2;
        mCenterY = 92;
	    setMeasuredDimension(mViewWidth, mViewHeight);
	}
	
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		canvas.save();
		
		
		float angel = (DURING_ARC * (mPercent - mMinValue) / (mMaxValue - mMinValue)); // 指针与水平线夹角
		canvas.rotate(angel, mCenterX, mCenterY);
		
		mPaint.setStyle(Style.FILL);
		mPaint.setStrokeWidth(2);
		mPaint.setColor(Color.RED);
		canvas.drawCircle(mCenterX-innerRadios/3*2+pointRadiosOfset, mCenterY, pointRadios, mPaint);
		
		canvas.translate(mCenterX-innerRadios/3*2+pointRadiosOfset, mCenterY);
		
		mPath.moveTo(0, -pointRadios);
		mPath.lineTo(0, -pointRadios);
		mPath.lineTo(-pointLenght, 0);
		mPath.lineTo(0, pointRadios);
		mPath.close();
		canvas.drawPath(mPath, mPaint);
		
		
		canvas.restore();
		
		canvas.translate(mCenterX, mCenterY);
		mPaint.setStyle(Style.STROKE);
		mPaint.setStrokeWidth(1);
		mPaint.setColor(Color.WHITE);
		mPaint.setTextSize(16);
		mPaint.setTextAlign(Paint.Align.CENTER);
		mPaint.getTextBounds(String.valueOf(mPercent), 0, String.valueOf(mPercent).length(), mRect);
		Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        float top = fontMetrics.top;
        float bottom = fontMetrics.bottom;
        int baseLineY = (int) (mRect.centerY() - top/2 - bottom/2);
		canvas.drawText(String.valueOf(mPercent), mRect.left,baseLineY, mPaint);
		canvas.restore();
	}
	public void setPercent(int percent) {
        mPercent = percent;
        invalidate();
    }
//	public void setPercent(float percent) {
//		mPercent = percent;
//		invalidate();
//	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值