Android基础控件——SeekBar的自定义,超短代码模仿抖音带有数字拖拽进度条
程序员文章站
2022-04-11 15:33:39
...
前言
在开发中,经常会遇到SeekBar组件的开发,一个高效的自定义SeekBar显得尤为重要,笔者刚好也在项目中大量使用带有数字的拖拽进度条,在深思熟虑后,打算从继承源码形式上,把数字绘制在拖拽进度条上,让拖拽的时候时刻去更新数字。这种实现方式不到100行代码,代码极其精简,功能极其好用,另外,这种方案可以用于各种组件绘制在进度条上方,这块的实现就看需求的具体效果
本例子中高仿抖音的进度拖拽效果,实现效果如下
实现思路
- 继承SeekBar,自定义属性
- 在onDraw方法增加数字的绘制和数字阴影的绘制
实现分析
1、快速使用
在xml直接使用,其监听进度变化同SeekBar组件
<com.baseui.seekbar.NumberSeekBar
android:layout_width="match_parent"
android:layout_height="54dp"
android:max="100"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:progressDrawable="@drawable/progress_seek_bar_beauty"
android:thumb="@drawable/icon_beauty_seek_bar_thumb"
app:textColor="@color/white"
app:textMarginBottom="2dp"
app:textShadowColor="#80000000"
app:textShadowOffsetX="0dp"
app:textShadowOffsetY="0dp"
app:textShadowRadius="2dp"
app:textSize="12sp"
app:withText="true"
app:withTextShadow="true"
tools:progress="50"/>
2、自定义属性
在attr中增加自定义的属性
<resources>
<declare-styleable name="InheritedSeekBar">
<attr name="withText" format="boolean" />
<attr name="textSize" format="dimension" />
<attr name="textColor" format="color" />
<attr name="textMarginBottom" format="dimension" />
<attr name="withTextShadow" format="boolean" />
<attr name="textShadowColor" format="color" />
<attr name="textShadowOffsetX" format="dimension" />
<attr name="textShadowOffsetY" format="dimension" />
<attr name="textShadowRadius" format="dimension" />
</declare-styleable>
</resources>
- withText:是否带有进度值
- textSize:进度值的大小
- textColor:进度值的颜色
- textMarginBottom:进度值底边距
- withTextShadow:是否带有进度值的阴影
- textShadowColor:进度值阴影的颜色
- textShadowOffsetX:进度值阴影的x坐标偏移
- textShadowOffsetY:进度值阴影的y坐标偏移
- textShadowRadius:进度值阴影的圆角
3、获取属性
通过attributeSet
获取自定义属性,同时获取进度的属性和进度阴影的属性
class NumberSeekBar @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatSeekBar(context, attrs, defStyleAttr) {
private val textPaint = Paint()
private var withText: Boolean = false
private var textSize: Float = 0f
private var textColor: Int = Color.BLACK
private var textMarginBottom: Int = 0
private var withTextShadow = false
private var textShadowColor = Color.BLACK
private var textShadowRadius = 0
private var textShadowOffsetX = 0
private var textShadowOffsetY = 0
init {
init(context, attrs)
}
private fun init(context: Context, attributeSet: AttributeSet?) {
val a: TypedArray = context.obtainStyledAttributes(attributeSet, R.styleable.InheritedSeekBar)
// 获取进度的属性
withText = a.getBoolean(R.styleable.InheritedSeekBar_withText, false)
if (withText) {
textSize = a.getDimensionPixelSize(R.styleable.InheritedSeekBar_textSize,
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
12f,
context.resources.displayMetrics).toInt()).toFloat()
textColor = a.getColor(R.styleable.InheritedSeekBar_textColor, textColor)
textMarginBottom = a.getDimensionPixelSize(R.styleable.InheritedSeekBar_textMarginBottom, 0)
}
// 获取进度阴影的属性
withTextShadow = a.getBoolean(R.styleable.InheritedSeekBar_withTextShadow, false)
if (withTextShadow) {
textShadowColor = a.getColor(R.styleable.InheritedSeekBar_textShadowColor, textShadowColor)
textShadowRadius = a.getDimensionPixelSize(R.styleable.InheritedSeekBar_textShadowRadius, 0)
textShadowOffsetX = a.getDimensionPixelOffset(R.styleable.InheritedSeekBar_textShadowOffsetX, 0)
textShadowOffsetY = a.getDimensionPixelOffset(R.styleable.InheritedSeekBar_textShadowOffsetY, 0)
}
a.recycle()
// 对画笔设置值和阴影
if (withText) {
textPaint.textSize = textSize
textPaint.color = textColor
textPaint.textAlign = Paint.Align.CENTER
}
if (withTextShadow) {
textPaint.setShadowLayer(textShadowRadius.toFloat(), textShadowOffsetX.toFloat(),
textShadowOffsetY.toFloat(), textShadowColor)
}
}
}
4、绘制数字和阴影
通过复写onDraw
方法,经过计算偏移量后,在进度拖拽的上方绘制数字
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (withText) {
drawText(canvas)
}
}
private fun drawText(canvas: Canvas) {
val saveCount = canvas.save()
val thumbTopY = thumb.bounds.top
// 计算拖拽组件的中点
val thumbCenterX = paddingStart + progress.toFloat() / max * (width - paddingStart - paddingEnd)
canvas.drawText(progress.toString(), thumbCenterX, thumbTopY.toFloat() - textMarginBottom, textPaint)
canvas.restoreToCount(saveCount)
}
5、进度条颜色
对于进度条颜色是layer-list
,可以设置进度的背景和进度颜色值,而进度拖拽组件,其实就是个圆形的Icon图片而已
android:progressDrawable="@drawable/progress_seek_bar"
android:thumb="@drawable/icon_beauty_seek_bar_thumb"
在progress_seek_bar
设置进度成黄色,背景成少许透明的灰黑色
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@android:id/background"
android:gravity="center_vertical">
<shape>
<solid android:color="#29ffffff" />
<corners android:radius="3dp" />
<size android:height="3dp" />
</shape>
</item>
<item
android:id="@android:id/secondaryProgress"
android:gravity="center_vertical">
<clip>
<shape>
<solid android:color="#29ffffff" />
<corners android:radius="3dp" />
<size android:height="3dp" />
</shape>
</clip>
</item>
<item
android:id="@android:id/progress"
android:gravity="center_vertical">
<clip>
<shape>
<solid android:color="#ffffe000" />
<corners android:radius="3dp" />
<size android:height="3dp" />
</shape>
</clip>
</item>
</layer-list>
上一篇: JAVA 爬虫 抖音视频
下一篇: 音视频多线程播放