Android自定义view:seekbar的简单处理

最近搬砖,嗯。

有一个seekbar,然后呢需要在thumb下面显示一个进度百分百的文字。然后样式和系统的长的不一样。所以需要简单处理下。

参考资料

正文

思路就那么几种,一种是基于seekbar,设置style,属性啥的。一种是自定义view啥都手写,最后一种就是继承seekbar,用他的逻辑,然后自己画。道理就很简单,自己整就行。

设置style或属性

首先定义xml:

ini 复制代码
<?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|fill_horizontal">
        <shape android:shape="rectangle">
            <size android:height="10dp" />
            <solid android:color="#282b31" />
            <corners android:radius="10dp" />
        </shape>
    </item>
    <item
        android:id="@android:id/progress"
        android:gravity="center_vertical|fill_horizontal">
        <scale android:scaleWidth="100%">
            <shape android:shape="rectangle">
                <size android:height="10dp" />
                <gradient
                    android:angle="0"
                    android:endColor="#aab8d4"
                    android:startColor="#707d93" />
                <corners android:radius="10dp" />
            </shape>
        </scale>
    </item>
    <item android:id="@android:id/secondaryProgress" android:gravity="center_vertical|fill_horizontal">
        <shape android:shape="rectangle">
            <size android:height="10dp" />
            <solid android:color="#282b31" />
            <corners android:radius="10dp" />
        </shape>
    </item>
    
</layer-list>

定义了几个id:

  • @android:id/background 进度条的背景。
  • @android:id/progress 这个玩意是进度条。
  • @android:id/secondaryProgress 缓冲进度。

借用一张图(上面blog中tou的,感觉很完美的契合了):

通过这张图,我们就非常直观的了解到了。整个seekbar 的绘制元素。

最后就是设置thumb,这个肯定不能是SVG。thumb 也有样式。

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 按下状态 -->
    <item android:drawable="@drawable/shape_seekbar_btn" android:state_pressed="true" />
​
    <!-- 焦点状态 -->
    <item android:drawable="@drawable/shape_seekbar_btn" android:state_focused="true" />
​
    <!-- 选择状态 -->
    <item android:drawable="@drawable/shape_seekbar_btn" android:state_selected="true" />
​
    <!-- 默认状态 -->
    <item android:drawable="@drawable/shape_seekbar_btn" />
</selector>

OK,这么一套下来。剩下的就是监听seek,然后设置文本了。

基于继承AppCompatSeekBar的自定义

因为某些原因(不知道到thumb不能设置svg,至于为啥不能,还没有细看),当时搞切图的时候,把thumb导成svg了,做的时候又发现搞切图的平台打不开了。算了,反正都需要自定义,那就thumb 我也自己画,反正设置的svg 不显示。

绘制thumb和文本

我们需求很简单,对thumb也没有啥状态,就一直那个样式。即然我都导svg了,这path我非用不可了好吧。我们通过:

arduino 复制代码
 PathParser.createPathFromPathData("path")

这么就获取到了一个path对象。有一个问题,那就是path 对象创建成功后,就没法设置开始位置了,我们thumb总不能一直卡在某个角落吧,但是,山不转水转,我canvas自己动不行吗?

  • canvas.translate() 平移
  • Matrix().postTranslate()也可以平移,canvas.setMatrix()

移动canvas有一个好处,那就是绘制文本的时候,不需要计算文本在x 轴的位置了,thumb绘制的时候已经平移了,一箭双雕,完美。剩下的就简单了,通过canvas.drawPath()和drawText() 即可。

绘制圆角矩形

当thumb 自己画的时候,已经走远了好吧。不同的手机跑出来thumb和进度条没有一个水平线上。OK,为了技术(填坑),进度和背景我也自己画。圆角矩形的path:

scss 复制代码
val path by lazy {
    Path().apply {
        val rectF = RectF(
            0f,
            0f,
            width ,
            height 
        )
        val radius = SizeUtils.dp2px(8f).toFloat()
        addRoundRect(
            rectF,
            radius, radius,
            Path.Direction.CW
        )
    }
}

seekbar 的进度和背景的区域就在rectf 中的right知不一样,但是不能用by lazy.所以通过函数返回即可。即然都自己画了,所以onDraw 中的supper就不需要了。

设置监听

这个就很简单了,就是在setOnSeekBarChangeListener于onProgressChanged函数中,调用invalidate()刷新绘制即可。

基于view自定义

我们上面基于seekbar 已经处理了绘制相关的逻辑了,基于view的自定义基本上就是基于onTouchEvent 分发event事件了。

  • ACTION_DOWN 按下的时候,如果需求上是可以点击切换的的话,就不拦截,点哪里然后通过x或者y计算一个进度值,如果不支持点击切换,那么需要判断触摸区域是否是thumb所在区域。
  • ACTION_MOVE 移动也是一个道理,每次移动一定的量的时候触发一次刷新,或者每次移动都重新计算进度刷新。
  • ACTION_UP 抬起的时候,也更新进度,当然可以更新。

总结

整体来说,还是蛮简单的,当然留下了一个坑为什么VectorDrawable 通过.draw(canvas) 绘制不出来还没有看,同时canvas 绘制 svg的bitmap 和drawable 好像都不行。

作为2024年第一篇水文,每天留一点坑,年终总结的时候就会发现要填的太多了。

相关推荐
飞猿_SIR26 分钟前
android定制系统完全解除应用安装限制
android
索迪迈科技1 小时前
影视APP源码 SK影视 安卓+苹果双端APP 反编译详细视频教程+源码
android·影视app源码·sk影视
孔丘闻言1 小时前
python调用mysql
android·python·mysql
萧雾宇3 小时前
Android Compose打造仿现实逼真的烟花特效
android·flutter·kotlin
翻滚丷大头鱼4 小时前
android 性能优化—ANR
android·性能优化
翻滚丷大头鱼4 小时前
android 性能优化—内存泄漏,内存溢出OOM
android·性能优化
拜无忧4 小时前
【教程】flutter常用知识点总结-针对小白
android·flutter·android studio
拜无忧5 小时前
【教程】Flutter 高性能项目架构创建指南:从入门到高性能架构
android·flutter·android studio
用户2018792831675 小时前
故事:公司的 "私人储物柜" 系统(ThreadLocalMap)
android·java
CYRUS_STUDIO5 小时前
如何防止 so 文件被轻松逆向?精准控制符号导出 + JNI 动态注册
android·c++·安全