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年第一篇水文,每天留一点坑,年终总结的时候就会发现要填的太多了。

相关推荐
游戏开发爱好者83 小时前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码20353 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥3 小时前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓3 小时前
[JDBC]元数据
android
独行soc3 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能3 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿3 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc4 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
王码码20354 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
2501_915106324 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview