Android原生控件只有横向进度条一种,而且没法变换样式,比如原生rom的样子

很丑是吧,当伟大的产品设计要求更换前背景,甚至纵向,甚至圆弧状的,咋办,比如

ok,我们开始吧:

一)变换前背景

先来看看progressbar的属性:

  1. <ProgressBar
  2. android:id="@+id/progressBar"
  3. style="?android:attr/progressBarStyleHorizontal"
  4. android:layout_width="match_parent"
  5. android:layout_height="wrap_content"
  6. android:layout_margin="5dip"
  7. android:layout_toRightOf="@+id/progressBarV"
  8. android:indeterminate="false"
  9. android:padding="2dip"
  10. android:progress="50" />

根据style="?android:attr/progressBarStyleHorizontal",我们找到源码中的style.xml

  1. <style name="Widget.ProgressBar.Horizontal">
  2. <item name="android:indeterminateOnly">false</item>
  3. <item name="android:progressDrawable">@android:drawable/progress_horizontal</item>
  4. <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
  5. <item name="android:minHeight">20dip</item>
  6. <item name="android:maxHeight">20dip</item>
  7. </style>

看到

<item name="android:progressDrawable">@android:drawable/progress_horizontal</item>

木有,继续发掘源码,找到drawable下面的progress_horizontal.xml,这就是我们今天的主角了:

  1. <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  2. <item android:id="@android:id/background">
  3. <shape>
  4. <corners android:radius="5dip" />
  5. <gradient
  6. android:startColor="#ff9d9e9d"
  7. android:centerColor="#ff5a5d5a"
  8. android:centerY="0.75"
  9. android:endColor="#ff747674"
  10. android:angle="270"
  11. />
  12. </shape>
  13. </item>
  14. <item android:id="@android:id/secondaryProgress">
  15. <clip>
  16. <shape>
  17. <corners android:radius="5dip" />
  18. <gradient
  19. android:startColor="#80ffd300"
  20. android:centerColor="#80ffb600"
  21. android:centerY="0.75"
  22. android:endColor="#a0ffcb00"
  23. android:angle="270"
  24. />
  25. </shape>
  26. </clip>
  27. </item>
  28. <item android:id="@android:id/progress">
  29. <clip>
  30. <shape>
  31. <corners android:radius="5dip" />
  32. <gradient
  33. android:startColor="#ffffd300"
  34. android:centerColor="#ffffb600"
  35. android:centerY="0.75"
  36. android:endColor="#ffffcb00"
  37. android:angle="270"
  38. />
  39. </shape>
  40. </clip>
  41. </item>
  42. </layer-list>

看到android:id="@android:id/progress"木有,看到android:id="@android:id/secondaryProgress"木有

把这个文件复制到自己工程下的drawable,就可以随心所欲的修改shape的属性,渐变,圆角等等

那么怎么放一个图片进去呢,ok,新建progress_horizontal1.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:id="@android:id/progress" android:drawable="@drawable/progressbar" />
  4. </layer-list>

在android:drawable中指定你处理好的图片

然后回到布局中

  1. <ProgressBar
  2. android:id="@+id/progressBar1"
  3. android:layout_width="match_parent"
  4. android:layout_height="wrap_content"
  5. android:layout_below="@+id/progressBar"
  6. android:layout_margin="5dip"
  7. android:layout_toRightOf="@+id/progressBarV"
  8. android:background="@drawable/progress_bg"
  9. android:indeterminate="false"
  10. android:indeterminateOnly="false"
  11. android:maxHeight="20dip"
  12. android:minHeight="20dip"
  13. android:padding="2dip"
  14. android:progress="50"
  15. android:progressDrawable="@drawable/progress_horizontal1" />

android:background="@drawable/progress_bg"指定背景

android:progressDrawable="@drawable/progress_horizontal1"前景使用上面的progress_horizontal1

ok,搞定

注意看,四角还是有圆倒角的,貌似是系统自己加上去的,总之我的图片里面是没有做这个倒角处理的

二)纵向进度条

还是得从源码入手,看回progress_horizontal.xml

  1. <item android:id="@android:id/progress">
  2. <clip>
  3. <shape>
  4. <corners android:radius="5dip" />
  5. <gradient
  6. android:startColor="#ffffd300"
  7. android:centerColor="#ffffb600"
  8. android:centerY="0.75"
  9. android:endColor="#ffffcb00"
  10. android:angle="270"
  11. />
  12. </shape>
  13. </clip>
  14. </item>

为什么shape外面要包一层clip呢,官方文档解释是clipdrawable是可以自我复制的,来看看定义

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <clip
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:drawable="@drawable/drawable_resource"
  5. android:clipOrientation=["horizontal" | "vertical"]
  6. android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
  7. "fill_vertical" | "center_horizontal" | "fill_horizontal" |
  8. "center" | "fill" | "clip_vertical" | "clip_horizontal"] />

android:clipOrientation有两个属性,默认为horizontal

android:gravity有两个属性,默认为left

那我们试试改成vertical和bottom会有什么效果,新建一个progress_vertical.xml,把源码progress_horizontal.xml的内容复制过来,这里去掉了secondaryProgress,修改了clip,shape的渐变中心centerY改为centerX

  1. <item android:id="@android:id/progress">
  2. <clip
  3. android:clipOrientation="vertical"
  4. android:gravity = "bottom">
  5. <shape>
  6. <corners android:radius="5dip" />
  7. <gradient
  8. android:startColor="#ffffd300"
  9. android:centerColor="#ffffb600"
  10. android:centerX="0.75"
  11. android:endColor="#ffffcb00"
  12. android:angle="90"
  13. />
  14. </shape>
  15. </clip>
  16. </item>

布局中android:progressDrawable="@drawable/progress_vertical"

ok,搞定,就是这么简单:

三)弧形bar

这个也许算不上是进度条,用的也不多,最多也就仪表盘用用,不然谁会把进度条整成圆弧的呢。好吧这个可不是改改源码就能搞定的,看代码

  1. public class Arcs extends View {
  2. private Paint mArcPaint;
  3. private Paint mArcBGPaint;
  4. private RectF mOval;
  5. private float mSweep = 0;
  6. private int mSpeedMax = 200;
  7. private int mThreshold = 100;
  8. private int mIncSpeedValue = 0;
  9. private int mCurrentSpeedValue = 0;
  10. private float mCenterX;
  11. private float mCenterY;
  12. private float mSpeedArcWidth;
  13. private final float SPEED_VALUE_INC = 2;
  14. ..........
  15. }

首先是一堆成员变量,两个Paint用来画圆弧一个前景一个背景,一个RectF圆弧就画在上面,然后是一些控制参数比如sweep圆弧扫过的角度,xy坐标等等

  1. mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  2. mArcPaint.setStyle(Paint.Style.STROKE);
  3. mArcPaint.setStrokeWidth(mSpeedArcWidth);
  4. //        mPaint.setStrokeCap(Paint.Cap.ROUND);
  5. mArcPaint.setColor(0xff81ccd6);
  6. BlurMaskFilter mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.INNER);
  7. mArcPaint.setMaskFilter(mBlur);
  8. mArcBGPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  9. mArcBGPaint.setStyle(Paint.Style.STROKE);
  10. mArcBGPaint.setStrokeWidth(mSpeedArcWidth+8);
  11. mArcBGPaint.setColor(0xff171717);
  12. BlurMaskFilter mBGBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.INNER);
  13. mArcBGPaint.setMaskFilter(mBGBlur);

设置两个画笔,颜色,宽度,样式等等,BlurMaskFilter笔是边缘模糊效果,有几种,可以自己尝试

  1. @Override
  2. protected void onSizeChanged(int w, int h, int ow, int oh) {
  3. super.onSizeChanged(w, h, ow, oh);
  4. Log.i("onSizeChanged w", w+"");
  5. Log.i("onSizeChanged h", h+"");
  6. mCenterX = w * 0.5f;  // remember the center of the screen
  7. mCenterY = h - mSpeedArcWidth;
  8. mOval = new RectF(mCenterX - mCenterY, mSpeedArcWidth, mCenterX + mCenterY, mCenterY * 2);
  9. }

重写父类View的onSizeChanged,为的是自己根据布局中的大小做居中处理

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. drawSpeed(canvas);
  4. calcSpeed();
  5. }
  6. private void drawSpeed(Canvas canvas) {
  7. canvas.drawArc(mOval, 179, 181, false, mArcBGPaint);
  8. mSweep = (float) mIncSpeedValue / mSpeedMax * 180;
  9. if (mIncSpeedValue > mThreshold) {
  10. mArcPaint.setColor(0xFFFF0000);
  11. }
  12. else {
  13. mArcPaint.setColor(0xFF00B0F0);
  14. }
  15. canvas.drawArc(mOval, 180, mSweep, false, mArcPaint);
  16. }
  17. private void calcSpeed() {
  18. if (mIncSpeedValue < mCurrentSpeedValue) {
  19. mIncSpeedValue += SPEED_VALUE_INC;
  20. if (mIncSpeedValue > mCurrentSpeedValue) {
  21. mIncSpeedValue = mCurrentSpeedValue;
  22. }
  23. invalidate();
  24. }
  25. else if (mIncSpeedValue > mCurrentSpeedValue) {
  26. mIncSpeedValue -= SPEED_VALUE_INC;
  27. if (mIncSpeedValue < mCurrentSpeedValue) {
  28. mIncSpeedValue = mCurrentSpeedValue;
  29. }
  30. invalidate();
  31. }
  32. }

重写onDraw以便重绘canvas

drawSpeed里面

通过计算mSweep = (float) mIncSpeedValue / mSpeedMax * 180;

然后canvas.drawArc(mOval, 180, mSweep, false, mArcPaint);

会根据mSweep的变化,画出相应长度的弧度来

根据与阈值的对比,还可以设定不同的 颜色:

if (mIncSpeedValue > mThreshold) {

mArcPaint.setColor(0xFFFF0000);

}

else {

mArcPaint.setColor(0xFF00B0F0);

}

calcSpeed通过一个步进来控制增量或减量,以使弧度自然过渡,减少跳跃

ok,大功告成

android自定义seekBar的更多相关文章

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

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

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

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

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

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

  4. Android 自定义带刻度的seekbar

    自定义带刻度的seekbar 1.布局 <span style="font-family:SimHei;font-size:18px;"><com.imibaby ...

  5. Android 开发之网易云音乐(或QQ音乐)的播放界面转盘和自定义SeekBar的实现

    这个东西我在eoeAndroid上首发的,但没有详细的实现说明:http://www.eoeandroid.com/thread-317901-1-1.html 在csdn上进行详细的说明吧.(同时上 ...

  6. Android简易实战教程--第三十四话《 自定义SeekBar以及里面的一些小知识》

    转载本专栏文章,请注明出处尊重原创:博客地址http://blog.csdn.net/qq_32059827/article/details/52849676:小杨的博客 许多应用可能需要加入进度,例 ...

  7. 我的Android进阶之旅------>Android如何通过自定义SeekBar来实现视频播放进度条

    首先来看一下效果图,如下所示: 其中进度条如下: 接下来说一说我的思路,上面的进度拖动条有自定义的Thumb,在Thumb正上方有一个PopupWindow窗口,窗口里面显示当前的播放时间.在Seek ...

  8. 自定义SeekBar的使用

    一.seekbar是进度条,可以使用系统的,也可以自己定义,下面我们将自己定义一个seekbar. 1.自定义滑条,包括对背景,第一进度,第二进度的设置,通过一个xml来实现,在drawable下创建 ...

  9. Android使用SeekBar时动态显示进度且随SeekBar一起移动

    最近有做一个android项目,里面有使用到在播放视频时可以跳播,同时动态显示播放时间.类似于下图 的效果,我只是抽取其中的一部分做展示,刚接到这个事时也是在网上一通找,最后没找到!而且还碰到有些朋友 ...

随机推荐

  1. hdu 1231

    最大连续子序列 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Statu ...

  2. C++字符转码

    wchar_t* U8ToUnicode(char* szU8) { //UTF8 to Unicode //由于中文直接复制过来会成乱码,编译器有时会报错,故采用16进制形式 //char* szU ...

  3. Capistrano初探--Ruby快速部署工具

    1.Capistrano介绍 是什么?---一种部署工具.(部署就是在生产服务器上安装应用程序,或是更新最新版本:web服务器的启动重启与停止:使网站进入维护状态或将其恢复为常态) 在进行 Rails ...

  4. Windows2008当桌面使用

    因为需要32位系统,又想用8G内存. 一.提高开机速度   0 |" t7 A- d! `- A- R5 | 1.免除登录时按Ctrl+Alt+Del的限制 打开<开始> - & ...

  5. 3D扫描系统的构建(待处理)

    1. http://www.zhihu.com/question/32143353 是否可以 DIY 一个 3D 扫描仪或者开源 3D 扫描项目? 详细的原理介绍 2. http://www.csks ...

  6. 毫无保留开源我写的:IOS Android Ipad 多点触摸通用js 库

    毫无保留开源我写的:IOS Android Ipad 多点触摸通用js 库 在线演示地址: http://m.yunxunmi.com/ 支持 IOS Android Ipad 等不同操作系统的手持或 ...

  7. [Xamarin] 用Service 來製作一個Notification的時鐘 (转帖)

    這篇利用來製作一個會出現在Notification的時鐘,來敘述一下 Service,在你製作的App被關閉時,可以透過Service繼續運行你想處理的部分,當然Service 也有其生命周期 接下來 ...

  8. 【WinHec启示录】透过Windows 10技术布局,谈微软王者归来

    每个时代都有王者,王者的成功,往往是因为恰逢其时地发布了一个成功的产品(具有里程碑意义,划时代的产品).Windows 95的成功标示着微软是PC时代的王者:WinXP的成功标示着微软是互联网时代的王 ...

  9. 使用NHibernate(9)-- 缓存

    1,对象状态. 作为基础,还是先看一下对象的状态吧.主要涉及到三个名词,瞬时.持久.托管. 瞬时态:对象刚创建,Session还不知道这个对象的存在.可以通过调用ISession的Save等方法可以转 ...

  10. 跟我一起学WCF(7)——WCF数据契约与序列化详解

    一.引言 在前面博文介绍到,WCF的契约包括操作契约.数据契约.消息契约和错误契约,前面一篇博文已经结束了操作契约的介绍,接下来自然就是介绍数据契约了.所以本文要分享的内容就是数据契约. 二.数据契约 ...