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. 关于mysql占用CPU过高,问题解决

    使用SHOW PROCESSLIST 查看 原因: 使用了 一个触发器 不断的去删除日志,保证每个用户的日志只有10条 去掉之后,CPU使用率从97% 降到了 %. 利用show columns fr ...

  2. JQuery学习(选择器-基本-*)

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  3. 应用框架的设计与实现——.NET平台(10 授权服务.CodeAccessSecurityAttribute)

    以下内容转载自:http://blog.csdn.net/dongma_yifei/article/details/1533124 CodeAccessSecurityAttribute 是 Prin ...

  4. ASP.NET MVC5 与EF6学习系列

    最近学习使用MVC5和EF6,博客园搜索了一番,写下这篇文章记录,以便学习使用. 一.ASP.NET MVC5 网站开发 @洞庭夕照写的博客系列 ASP.NET MVC5 网站开发实践 - 概述 AS ...

  5. Windows 8.1 应用开发后台任务概述(Windows XAML)

    说到后台任务,这是在和许多 Android 开发者聊天的时候,经常被提起的话题之一, Windows 移动平台的后台任务的形式有别与 Android 的后台 service,简单的说在 Windows ...

  6. 跟我一起学WCF(3)——利用Web Services开发分布式应用

    一.引言 在前面文章中分别介绍了MSMQ和.NET Remoting技术,今天继续分享.NET 平台下另一种分布式技术——Web Services 二.Web Services 详细介绍 2.1 We ...

  7. linux下svn定时更新项目

    方法一.用shell脚本定时更新项目   1.进入网站的根目录,假设项目位置放在/var/www/test cd /var/www/test   2.建立脚本文件update.sh,分两步进行.首先利 ...

  8. 理解assign,copy,retain变strong

    举个例子: NSString *houseOfMM = [[NSString alloc] initWithString:'装梵几的三室两厅']; 上面一段代码会执行以下两个动作:  1 在堆上分配一 ...

  9. HTTP权威指南阅读笔记二:URL与资源

    URL中的限制字符: 在URL中,有几个字符被保留起来,有着特殊的含义.有些字符不在定义的US-ASCII可打印字符集中.还有些字符会与某些因特网网关和协议产生混淆,因此不赞成使用. 下面这些字符是U ...

  10. nginx upstream模块--负载均衡

    Module ngx_http_upstream_module英文文档 upstream模块相关说明1.upstream模块应放于nginx.conf配置的http{}标签内2.upstream模块默 ...