SeekBar的样式修改及分析
来源:互联网 发布:手机淘宝人工客服 编辑:程序博客网 时间:2024/06/11 08:02
今天在看视频的时候感觉视频底部的SeekBar样式还不错,所以就亲手实践改了一下系统默认的样式。
这里我先做了一个SeekBar的结构分析图:
先看一下效果,不是很炫酷,上面的是我的,下面的是系统原生的样式,没有人家的那么迷你,只想让你看的更清楚
首先我去系统的values.xml搜索SeekBar,搜索结果如下
<style name="Base.Widget.AppCompat.SeekBar" parent="android:Widget"> <item name="android:indeterminateOnly">false</item> <item name="android:progressDrawable">@drawable/abc_seekbar_track_material</item> <item name="android:indeterminateDrawable">@drawable/abc_seekbar_track_material</item> <item name="android:thumb">@drawable/abc_seekbar_thumb_material</item> <item name="android:focusable">true</item> <item name="android:paddingLeft">16dip</item> <item name="android:paddingRight">16dip</item> </style>
方式一
我们只要修改android:progressDrawable和android:thumb这个就可以达到自己想要的效果,所以将这两个属性Copy出来,在我们自己的styles.xml中创建如下style即可:
<style name="jrt_seekbar_style" parent="Base.Widget.AppCompat.SeekBar"> <item name="android:progressDrawable">@drawable/my_seekbar_style</item> <item name="android:thumb">@drawable/seekbar_thumb</item> </style>
接下来开启照猫画虎模式
my_seekbar_style这个drawable的写法我们去参靠系统的abc_seekbar_track_material.xml,直接一个copy在我们的drawable目录下,然后改成我们自己的文件名字,如:my_seekbar_style.xml;具体如下:
<?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:drawable="@drawable/seekbar_bg"/> <item android:id="@android:id/secondaryProgress"> <scale android:scaleWidth="100%"> <selector> <item android:state_enabled="false"> <color android:color="@android:color/transparent"/> </item> <item android:drawable="@drawable/seekbar_progress_2"/> </selector> </scale> </item> <item android:id="@android:id/progress"> <scale android:scaleWidth="100%"> <selector> <item android:state_enabled="false"> <color android:color="@android:color/transparent"/> </item> <item android:drawable="@drawable/seekbar_progress"/> </selector> </scale> </item></layer-list>
其实这些代码都是google工程师写好的,我们只要把对应的drawable换成我们自己的即可。在layout应用的时候直接给Seekbar设置style属性即可;
<SeekBar android:id="@+id/seekBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_marginTop="140dp" style="@style/jrt_seekbar_style" />
方式二
我们不用在styles.xml中设置属性,将my_seekbar_style.xml和seekbar_thumb两个资源准备好了直接在layout中使用。如下:
<SeekBar android:id="@+id/myseekBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:progress="30" android:thumb="@drawable/seekbar_thumb" android:progressDrawable="@drawable/my_seekbar_style" />
做过开发的都知道这两种使用方式的要根据具体的场景而定,主要取决与你的SeekBar使用频率,如果只用一次就用方式二,如果多次,并且全局都使用同样的Seekbar那就用方式一,这样更体现了封装抽取,便于项目的维护和管理。其实应该还有方式三,在java代码中设置其属性。接下来说说踩多的坑,程序员都是踩着坑成长的。
坑
my_seekbar_style.xml在写的时候一定要按系统android:id的顺序来,不要随便改变item的顺序,必须是background->secondaryProgress->progress;我一开始没有copy系统代码,直接手写就掉坑里了把id顺序写成background->-progress>secondaryProgress;结果就成这样了,如图:
蓝色本来是progress应该随拖动的按钮变化而变化的,结果成了secondaryProgress缓冲进度了,刚好两个交换位置了,层级关系乱了。如果顺序写成secondaryProgress->progress->background那就更抽象了,直接把背景放到最顶层了,其他都被这挡了,如下图:
这个错误犯得好,让我明白了SeekBar是完全按照background->secondaryProgress->progress这个从低往高的层级关系显示UI的
最后来看一下SeekBar的源码
由上面的类关系集成图可以看出,SeekBar继承 AbsSeekBar,所以SeekBar本身没做什么工作,我们用到的就是它的一个内部接口回调OnSeekBarChangeListener,通过这个回调操作SeekBar不同状态下的操作。
public interface OnSeekBarChangeListener { /** * Notification that the progress level has changed. Clients can use the fromUser parameter * to distinguish user-initiated changes from those that occurred programmatically. * * @param seekBar The SeekBar whose progress has changed * @param progress The current progress level. This will be in the range 0..max where max * was set by {@link ProgressBar#setMax(int)}. (The default value for max is 100.) * @param fromUser True if the progress change was initiated by the user. */ void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser); /** * Notification that the user has started a touch gesture. Clients may want to use this * to disable advancing the seekbar. * @param seekBar The SeekBar in which the touch gesture began */ void onStartTrackingTouch(SeekBar seekBar); /** * Notification that the user has finished a touch gesture. Clients may want to use this * to re-enable advancing the seekbar. * @param seekBar The SeekBar in which the touch gesture began */ void onStopTrackingTouch(SeekBar seekBar); }
再看看AbsSeekBar继承于ProgressBar,通过下面AbsSeekBar源码中drawThumb(canvas)可以看出AbsSeekBar是在ProgressBar基础上多绘制了一个thumb,也就多了一个手指拖动进度的功能。所以SeekBar本身没有参与UI样式的修改工作,我们修改的progressDrawable是ProgressBar的,修改的thumb是AbsSeekBar的。还有一个就是SeekBar的子类AppCompatSeekBar,AppCompatSeekBar内部封装了一个AppCompatSeekBarHelper就是便于我们操作的,具体自己看源码。
@Override protected synchronized void onDraw(Canvas canvas) { super.onDraw(canvas); drawThumb(canvas); } @Override void drawTrack(Canvas canvas) { final Drawable thumbDrawable = mThumb; if (thumbDrawable != null && mSplitTrack) { final Insets insets = thumbDrawable.getOpticalInsets(); final Rect tempRect = mTempRect; thumbDrawable.copyBounds(tempRect); tempRect.offset(mPaddingLeft - mThumbOffset, mPaddingTop); tempRect.left += insets.left; tempRect.right -= insets.right; final int saveCount = canvas.save(); canvas.clipRect(tempRect, Op.DIFFERENCE); super.drawTrack(canvas); drawTickMarks(canvas); canvas.restoreToCount(saveCount); } else { super.drawTrack(canvas); drawTickMarks(canvas); } }
总结
最后那部分不是在做源码解析,我只是发表个人观点,如果有什么不对的可以,在下面留言,相互学习。知识在于探索,更在于创新。还是老话,举一反三。
- SeekBar的样式修改及分析
- SeekBar样式修改
- 修改SeekBar样式
- Android下修改SeekBar样式
- Android下修改SeekBar样式
- Android下修改SeekBar样式
- Android下修改SeekBar样式
- Android下修改SeekBar样式
- Android下修改SeekBar样式
- Android下修改SeekBar样式
- Android下修改SeekBar样式
- Android中如何修改SeekBar的默认样式
- Android学习笔记--如何修改SeekBar的样式
- SeekBar 的自定义样式
- 关于 seekbar 的样式
- 自定义seekBar的样式
- Seekbar自定义样式及使用
- 【SeekBar】Android 自定义漂亮的SeekBar样式
- 朝花夕拾-致我的2016
- python 多excel导入到mysql中去
- java异常
- 欢迎使用CSDN-markdown编辑器
- javascript学习(一)——第一部分 JavaScript语言核心
- SeekBar的样式修改及分析
- 单点登录实现(spring session+redis完成session共享)
- 嵌入式软件工程师经典笔试题
- Spring整合webservice CXF框架
- oracle sql优化
- hdu 1233&&九度oj 1017还是畅通工程
- 基于软引用的单例缓存
- 深入解析Android的自定义布局
- boost::variant的简单介绍