自定义控件之绘图篇(三)区域(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); // 设置选定范围

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/867571.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6800和8080单片机读写时序和液晶屏接口

前言&#xff1a; 随着单片机发展&#xff0c;集成度越来越高&#xff0c;因此目前单片机较少使用RD和WR信号操作外设&#xff0c;因此很多时候&#xff0c;变成了6800和8080单片机读写液晶屏了。早期的读写本质上是对一个地址进行即时的操作&#xff0c;现在可能是等数据送到…

网易游戏员工怒怼丁磊上热搜:每天员工陪你演戏点赞有意思吗

【头部财经】近日&#xff0c;网易游戏一员工在内部群怒怼丁磊的聊天记录曝光&#xff0c;引发网友关注。据头部财经了解&#xff0c;该员工名叫石佳煊&#xff0c;是网易游戏的游戏开发工程师&#xff0c;毕业于华盛顿大学&#xff0c;已在网易工作四年多。 截图显示&#xf…

【国产开源可视化引擎Meta2d.js】铅笔

铅笔 铅笔是可以任意涂鸦的绘图小工具 在线体验&#xff1a; 乐吾乐2D可视化 示例&#xff1a; // 开始铅笔绘画 meta2d.drawingPencil();// 鼠标抬起结束// 停止铅笔绘画&#xff08;关闭铅笔绘画状态&#xff09; meta2d.stopPencil(); 国产开源 乐吾乐潜心研发&#xff…

基于星火大模型的群聊对话分角色要素提取挑战赛

赛事任务与数据 2024 iFLYTEK A.I.开发者大赛-讯飞开放平台 (xfyun.cn) 从给定的<客服>与<客户>的群聊对话中, 提取出指定的字段信息&#xff0c;待提取的全部字段见下数据说明。 赛题方提供了184条真实场景的群聊对话数据以及人工标注后的字段提取结果&#xf…

AIGC专栏12——EasyAnimateV3发布详解 支持图文生视频 最大支持960x960x144帧视频生成

AIGC专栏12——EasyAnimateV3发布详解 支持图&文生视频 最大支持960x960x144帧视频生成 学习前言项目特点生成效果相关地址汇总项目主页Huggingface体验地址Modelscope体验地址源码下载地址 EasyAnimate V3详解技术储备Diffusion Transformer (DiT)Hybrid Motion ModuleU-V…

XXL-JOB中断信号感知

目录 背景 思路 实现逻辑 总结 背景 在使用xxl-job框架时&#xff0c;由于系统是由线程池去做异步逻辑&#xff0c;然后主线程等待&#xff0c;在控制台手动停止时&#xff0c;会出现异步线程不感知信号中断的场景&#xff0c;如下场景 而此时如果人工在控制台停止xxl-job执…

笔记13:switch多分支选择语句

引例&#xff1a; 输入1-5中的任意一共数字&#xff0c;对应的打印字符A,B,C,D,E int num 0; printf("Input a number[1,5]:"); scanf("%d"&#xff0c;&num); if( num 1)printf("A\n"); else if(num2)printf("B\n"); else i…

Alibaba Cloud Toolkit前端使用proxy代理配置

1、vscode 先安装插件 Alibaba Cloud Toolkit 2、前端代码&#xff1a; /personnel: {// target: http://xxx.xx.xxx.xx:9100, // 测试环境// target: http://xxx.xx.xxx.xx:9200, // 线上环境target: http://127.0.0.1:18002, // toolkit 代理changeOrigin: true,},3、打开插…

Android LayoutInflater 深度解析

在 Android 开发中&#xff0c;LayoutInflater 是一个非常重要的工具。它允许我们从 XML 布局文件中动态地创建 View 对象&#xff0c;从而使得 UI 的创建和管理更加灵活。本文将深入解析 android.view.LayoutInflater&#xff0c;包括它的基本用法、常见问题以及高级用法。 什…

MySQL架构和工作流程

引言&#xff1a;MySQL执行一条sql语句期间发生了什么&#xff1f; 想要搞清楚这个问题&#xff0c;我们必须了解MySQL的体系结构和工作流程 一、MySQL体系结构 MySQL由以下几个部分组成 一、server层 1.MySQL Connnectors连接器&#xff0c;MySQL的连接池组件&#xff0c;…

数据结构+算法-实现一个计算器

在学习栈的数据结构的时候讲到可以用栈来实现一个计算器的功能&#xff0c;那么这个功能是如何实现的呢&#xff1f; 采用栈模拟得方式来实现一个计算器 要实现如下的功能: 字符串如何转为整数 2.处理加减法 如何处理加减法呢&#xff1f; 5-128 给第一个数字前面放一个号…

UEC++ 虚幻5第三人称射击游戏(二)

UEC++ 虚幻5第三人称射击游戏(二) 派生榴弹类武器 新建一个继承自Weapon的子类作为派生榴弹类武器 将Weapon类中的Fire函数添加virtual关键字变为虚函数让榴弹类继承重写 在ProjectileWeapon中重写Fire函数,新建生成投射物的模版变量 Fire函数重写逻辑 代码//生成的投射物U…

从文本到安全图像:自动提示优化防止不当内容生成

T2I生成技术已经得到了广泛关注&#xff0c;并见证了如GLIDE、Imagen、DALL-E 2、Stable Diffusion等大型生成模型的发展。尽管这些模型能够根据文本描述生成高质量的图像&#xff0c;促进了书籍插图、品牌标识设计、游戏场景创作等多种实际应用&#xff0c;但它们也被恶意用户…

使用京东云主机搭建幻兽帕鲁游戏联机服务器全流程,0基础教程

使用京东云服务器搭建幻兽帕鲁Palworld游戏联机服务器教程&#xff0c;非常简单&#xff0c;京东云推出幻兽帕鲁镜像系统&#xff0c;镜像直接选择幻兽帕鲁镜像即可一键自动部署&#xff0c;不需要手动操作&#xff0c;真正的新手0基础部署幻兽帕鲁&#xff0c;阿腾云整理基于京…

Python学习笔记30:进阶篇(十九)pygame的使用之显示与窗口管理

前言 基础模块的知识通过这么长时间的学习已经有所了解&#xff0c;更加深入的话需要通过完成各种项目&#xff0c;在这个过程中逐渐学习&#xff0c;成长。 我们的下一步目标是完成python crash course中的外星人入侵项目&#xff0c;这是一个2D游戏项目。在这之前&#xff…

YOLOv8改进 | 注意力机制 | 结合静态和动态上下文信息的注意力机制

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

力扣双指针算法题目:双数之和,三数之和,四数之和

目录 一&#xff1a;双数之和 1.题目&#xff1a; 2.思路解析 3.代码 二&#xff1a;三数之和 1.题目 2.思路解析 3&#xff0c;代码 三&#xff1a;四数字之和 1.题目 2.思路解析 3.代码 一&#xff1a;双数之和 1.题目&#xff1a; 输入一个递增排序的数组和一…

贵州建筑三类人员安全员2024年考试最新题库练习题

一、单选题 1.建设工程安全管理的方针是&#xff08;&#xff09;。 A.安全第一&#xff0c;预防为主&#xff0c;综合治理 B.质量第一&#xff0c;兼顾安全 C.安全至上 D.安全责任重于泰山 答案&#xff1a;A 2.安全生产管理的根本目的是&#xff08;&#xff09;。 A.…

Lunaproxy与711Proxy的对比与优劣分析

今天我们来深入对比两款在市场上备受关注的代理IP服务&#xff1a;Lunaproxy和711Proxy。接下来&#xff0c;我们将从多个角度对这两款服务进行详细分析&#xff0c;帮助大家做出明智的选择。 优势分析 711Proxy的优势 1. 性价比高&#xff1a;711Proxy提供多种灵活的套餐选…

伪元素content追加文字使用小技巧

E::before和E::after本身的作用是追加字&#xff0c;直接在文字后面追加链接 <!DOCTYPE html> <html lang"zh-cn"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sca…