自定义控件之绘图篇(三)区域(Range)

在Android开发中,自定义控件经常需要处理各种类型的绘图需求,包括但不限于按钮、滑块、进度条等。对于涉及范围(Range)概念的控件,比如滑动选择器、时间线指示器或是数值范围选择器,实现起来需要对CanvasPaint有深入的理解。接下来,我将向你展示如何在自定义控件中实现一个范围指示器,它可以显示一个或多个可选的范围值。

自定义Range控件

我们将创建一个自定义View,该View能够显示一个水平的范围指示器,其中包含一个或两个可拖动的手柄,用于设定范围的最小值和最大值。

创建自定义View

首先,定义一个名为RangeIndicatorView的自定义View:

Java

1public class RangeIndicatorView extends View {
2
3    private static final int DEFAULT_MIN_VALUE = 0;
4    private static final int DEFAULT_MAX_VALUE = 100;
5    private static final int DEFAULT_SELECTED_MIN_VALUE = 20;
6    private static final int DEFAULT_SELECTED_MAX_VALUE = 80;
7    private static final int TRACK_HEIGHT = 30;
8    private static final int THUMB_RADIUS = 15;
9
10    private Paint trackPaint;
11    private Paint thumbPaint;
12    private RectF trackRect;
13    private float minValue, maxValue;
14    private float selectedMinValue, selectedMaxValue;
15    private float thumbLeftPos, thumbRightPos;
16
17    public RangeIndicatorView(Context context) {
18        this(context, null);
19    }
20
21    public RangeIndicatorView(Context context, @Nullable AttributeSet attrs) {
22        this(context, attrs, 0);
23    }
24
25    public RangeIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
26        super(context, attrs, defStyleAttr);
27        init();
28    }
29
30    private void init() {
31        // 初始化画笔
32        trackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
33        trackPaint.setColor(Color.GRAY);
34        trackPaint.setStyle(Paint.Style.FILL);
35
36        thumbPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
37        thumbPaint.setColor(Color.RED);
38        thumbPaint.setStyle(Paint.Style.FILL);
39
40        // 设置默认值
41        minValue = DEFAULT_MIN_VALUE;
42        maxValue = DEFAULT_MAX_VALUE;
43        selectedMinValue = DEFAULT_SELECTED_MIN_VALUE;
44        selectedMaxValue = DEFAULT_SELECTED_MAX_VALUE;
45
46        trackRect = new RectF();
47
48        // 更新手柄位置
49        updateThumbPositions();
50    }
51
52    @Override
53    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
54        super.onSizeChanged(w, h, oldw, oldh);
55        // 当View尺寸改变时,重新计算Track的RectF
56        calculateTrackRect();
57    }
58
59    @Override
60    protected void onDraw(Canvas canvas) {
61        super.onDraw(canvas);
62        // 绘制Track
63        canvas.drawRect(trackRect, trackPaint);
64        // 绘制左边手柄
65        canvas.drawCircle(thumbLeftPos, getHeight() / 2, THUMB_RADIUS, thumbPaint);
66        // 绘制右边手柄
67        canvas.drawCircle(thumbRightPos, getHeight() / 2, THUMB_RADIUS, thumbPaint);
68    }
69
70    private void calculateTrackRect() {
71        int width = getWidth();
72        int height = getHeight();
73        trackRect.set(0, (height - TRACK_HEIGHT) / 2, width, (height + TRACK_HEIGHT) / 2);
74    }
75
76    private void updateThumbPositions() {
77        int width = getWidth();
78        thumbLeftPos = (selectedMinValue - minValue) / (maxValue - minValue) * width;
79        thumbRightPos = (selectedMaxValue - minValue) / (maxValue - minValue) * width;
80    }
81
82    public void setRange(float min, float max) {
83        minValue = min;
84        maxValue = max;
85        updateThumbPositions();
86        invalidate();
87    }
88
89    public void setSelectedRange(float min, float max) {
90        selectedMinValue = min;
91        selectedMaxValue = max;
92        updateThumbPositions();
93        invalidate();
94    }
95}
关键点解析
  • 初始化:在构造函数中,我们创建了两个Paint对象,分别用于绘制轨道(Track)和手柄(Thumb)。我们还设置了默认的范围值和选定范围值,并初始化了RectF对象用于存储Track的边界。

  • onSizeChanged:当View的大小发生变化时,这个方法会被调用来重新计算Track的RectF

  • onDraw:这是绘制的主要逻辑,我们在这里绘制Track和两个手柄。

  • calculateTrackRect:根据当前View的宽度和高度计算Track的位置。

  • updateThumbPositions:根据选定的范围值计算手柄应该出现在哪个位置。

  • setRangesetSelectedRange:允许外部调用者设置范围和选定范围。

使用自定义View

现在,你可以在布局文件中使用这个自定义View了:

Xml

1<com.example.yourpackage.RangeIndicatorView
2    android:id="@+id/range_indicator_view"
3    android:layout_width="match_parent"
4    android:layout_height="wrap_content"/>

并且在Activity中可以通过findViewById找到它并设置范围:

Java

1RangeIndicatorView rangeIndicatorView = findViewById(R.id.range_indicator_view);
2rangeIndicatorView.setRange(0, 100); // 设置总范围
3rangeIndicatorView.setSelectedRange(20, 80); // 设置选定范围

这个自定义控件提供了一个基础框架,你可以根据具体需求进一步扩展其功能,例如添加触摸事件处理来实现手柄的拖拽操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值