一、前言

本文在 上节 的基础上,讲解自定义拖动条的实现思路。

二、思路

先在res/values文件夹下,自定义控件属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MySeekBar"> <attr name="progress_max" format="float|reference"/> <!-- 进度条最大值 -->
<attr name="progress_min" format="float|reference"/> <!-- 进度条最小值 -->
<attr name="progress_default" format="float|reference"/> <!-- 进度条默认值 --> <attr name="track_left_height" format="dimension|reference"/> <!-- 进度条左边高度 -->
<attr name="track_right_height" format="dimension|reference"/> <!-- 进度条右边高度 --> <attr name="track_left_color" format="color|reference"/> <!-- 进度条左边颜色 -->
<attr name="track_right_color" format="color|reference"/> <!-- 进度条右边颜色 --> <attr name="thumb_color_default" format="color|reference"/> <!-- 拖动滑块默认颜色 -->
<attr name="thumb_radius_default" format="dimension|reference"/> <!-- 拖动滑块半径 --> <attr name="thumb_color_on_dragging" format="color|reference"/> <!-- 拖动滑块拖动中颜色 -->
<attr name="thumb_radius_on_dragging" format="dimension|reference"/> <!-- 拖动滑块拖动中半径 --> </declare-styleable>
</resources>

由上可知,考虑绘制拖动条必要的几个基本属性,如最大值最小值及其默认值,显示拖动效果或进度的左右高度、颜色,以及滑块的半径和颜色。默认自左往右,故进度条左边高右边稍低,而滑块需要比左边更大一些。

对应SeekBar的构造函数:

public MySeekBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MySeekBar, defStyleAttr, 0); this.progress_max = typedArray.getFloat(R.styleable.MySeekBar_progress_max, 100);
this.progress_min = typedArray.getFloat(R.styleable.MySeekBar_progress_min, 0);
this.progress_default = typedArray.getFloat(R.styleable.MySeekBar_progress_default, progress_min); this.track_left_height = typedArray.getDimensionPixelSize(R.styleable.MySeekBar_track_left_height, DimensionUtil.dp2px(8));
this.track_right_height = typedArray.getDimensionPixelSize(R.styleable.MySeekBar_track_right_height, track_left_height - DimensionUtil.dp2px(2)); this.track_left_color = typedArray.getColor(R.styleable.MySeekBar_track_left_color, Color.BLUE);
this.track_right_color = typedArray.getColor(R.styleable.MySeekBar_track_right_color, Color.LTGRAY); this.thumb_color_default = typedArray.getColor(R.styleable.MySeekBar_thumb_color_default, track_left_color);
this.thumb_radius_default = typedArray.getDimensionPixelSize(R.styleable.MySeekBar_thumb_radius_default, track_left_height + DimensionUtil.dp2px(2)); this.thumb_color_on_dragging = typedArray.getColor(R.styleable.MySeekBar_thumb_color_on_dragging, thumb_color_default);
this.thumb_radius_on_dragging = typedArray.getDimensionPixelSize(R.styleable.MySeekBar_thumb_radius_on_dragging, thumb_radius_default + DimensionUtil.dp2px(2)); typedArray.recycle(); thumb_radius = thumb_radius_default; initPaint(); // 初始化画笔
}

由于其他基础知识点已于前面 Android 自定义View部分讲解,此处不再赘述。着重讲解 onMeasure(测量) 部分。先上代码

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 仅当 android_layout_width = wrap_content 或未指定时生效,若测出来的size大于你所指定的size (譬如这里是180dp),则使用所指定的size
int width = resolveSize(DimensionUtil.dp2px(180), widthMeasureSpec);
int height = thumb_radius_on_dragging * 2; // 控件高度按拖动时的滑块直径
setMeasuredDimension(width, height); // 强制指定控件大小 xLeft = getPaddingLeft() + thumb_radius_on_dragging; // 实际的绘图区域按距离父布局左边 padding 算起
xRight = getMeasuredWidth() - getPaddingRight() - thumb_radius_on_dragging; // 到距离父布局右边的的 padding 结束
yCenter = getPaddingTop() + thumb_radius_on_dragging; // 确定绘制进度条Y轴意义上的中点
}

此处有个resolveSize() 函数,这个函数继承自view类,效果是当用户没有给控件指定大小的时候,可以给它一个默认的大小。我们可以点进去看下该方法的具体实现:

/**
* Version of {@link #resolveSizeAndState(int, int, int)}
* returning only the {@link #MEASURED_SIZE_MASK} bits of the result.
*/
public static int resolveSize(int size, int measureSpec) {
return resolveSizeAndState(size, measureSpec, 0) & MEASURED_SIZE_MASK;
}

Android 自定义SeekBar (二)的更多相关文章

  1. Android自定义视图二:如何绘制内容

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

  2. Android自定义Seekbar拖动条式样

    SeekBar拖动条可以由用户控制,进行拖动操作.比如,应用程序中用户需要对音量进行控制,就可以使用拖动条来实现. 1.SeekBar控件的使用 1.1SeekBar常用属性 SeekBar的常用属性 ...

  3. Android自定义View (二) 进阶

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125 继续自定义View之旅,前面已经介绍过一个自定义View的基础的例 ...

  4. Android 自定义View (二) 进阶

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125 继续自定义View之旅,前面已经介绍过一个自定义View的基础的例 ...

  5. Android 自定义seekbar中,thumb被覆盖掉一部分问题

    (图一)  (图二)    (图三) 做一个自定义的seekbar,更改其背景图片: <com.android.Progress android:id="@+id/focus_seek ...

  6. Android自定义Seekbar滑动条,Pop提示跟随滑动按钮一起滑动

    由于项目需要做出此效果,自定义写了一个. 效果图 思路: 原始的seekbar只有滑动条并没有下方的提示文字,所以我们必须要继承Seekbar重写这个控件. 代码: 在values文件夹下新建attr ...

  7. android自定义seekBar

    Android原生控件只有横向进度条一种,而且没法变换样式,比如原生rom的样子 很丑是吧,当伟大的产品设计要求更换前背景,甚至纵向,甚至圆弧状的,咋办,比如 ok,我们开始吧: 一)变换前背景 先来 ...

  8. Android 自定义View二(深入了解自定义属性attrs.xml)

    1.为什么要自定义属性 要使用属性,首先这个属性应该存在,所以如果我们要使用自己的属性,必须要先把他定义出来才能使用.但我们平时在写布局文件的时候好像没有自己定义属性,但我们照样可以用很多属性,这是为 ...

  9. Android自定义视图四:定制onMeasure强制显示为方形

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

  10. Android自定义视图三:给自定义视图添加“流畅”的动画

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

随机推荐

  1. (K8s学习笔记七)Pod的升级和回滚

    1.Deployment的升级 示例:滚动升级busybox-deployment容器 apiVersion: apps/v1 kind: Deployment metadata: name: bus ...

  2. 城市间最短路径问题——R和Rcpp实现

    这里的最短路径问题也叫做相识问题,具体问题来自 https://www.math.pku.edu.cn/teachers/lidf/docs/Rbook/html/_Rbook/examples.ht ...

  3. oracle WMSYS.WM_CONCAT 函数使用

    1.用法 WMSYS.WM_CONCAT(要连接的字段) 该函数返回来自同一个分组的指定字段的非NULL值的连接起来字符串,默认逗号连接,一般搭配分组函数使用 2.示例 select XFJ_ID,R ...

  4. vm虚拟机和主机之间互传文件

    u盘大家都有吧,用u盘吧,超方便! vmtools 从主机传文件到虚拟机 可以通过之间复制粘贴/拖拽 或者共享文件夹的方式 从虚拟机传文件到主机,查到了说说是要在虚拟机里面改一个什么映射设置,改完之后 ...

  5. js 判断gps是否超出设定范围

    var CKposition = { //经纬度转换成三角函数中度分表形式 rad: function (d) { return d * Math.PI / 180.0; }, // 根据经纬度计算距 ...

  6. chatgpt

    openAI 需要外国手机验证可以使用 当时注册的时候怎么都不成功,后来换了一个浏览器,还是怎么也不行,后再不知怎的就好了 还需要FQ,我用的是日本的线路

  7. Access denied You do not have access to chat.openai.com. The site owner may have set restrictions that prevent you from accessing the site.解决办法

    报错 Access denied You do not have access to chat.openai.com. The site owner may have set restrictions ...

  8. Python 集合常用方法

    数据类型:int/str/bool/list/dict/tuple/float/set   (set类型天生去重) 一.集合的定义 s = set()  #定义空集合 s = {'a','b','c' ...

  9. java功能-发送http请求

    一.发送json public void test() throws IOException { //参数封装--------------------------------------------- ...

  10. IDEA打包普通java项目并用java命令运行

    IDEA下打包为jar包,普通java项目(非web项目) 效果是将第三方jar包放到一个文件夹中(如lib),这样看起来清晰一些.如下图这种: 1.项目结构. 1.关键:modules 在<o ...