Android那些事儿之自定义进度条

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://winwyf.blog.51cto.com/4561999/857867

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

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

ok,我们开始吧:

一)变换前背景

先来看看progressbar的属性:


<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_toRightOf="@+id/progressBarV"
android:indeterminate="false"
android:padding="2dip"
android:progress="50" />

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


<style name="Widget.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@android:drawable/progress_horizontal</item>
<item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
<item name="android:minHeight">20dip</item>
<item name="android:maxHeight">20dip</item>
</style>

看到

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

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


<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="270"
/>
</shape>
</item>

<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="270"
/>
</shape>
</clip>
</item>

<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270"
/>
</shape>
</clip>
</item>

</layer-list>

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

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

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

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@android:id/progress" android:drawable="@drawable/progressbar" />

</layer-list>

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

然后回到布局中


<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/progressBar"
android:layout_margin="5dip"
android:layout_toRightOf="@+id/progressBarV"
android:background="@drawable/progress_bg"
android:indeterminate="false"
android:indeterminateOnly="false"
android:maxHeight="20dip"
android:minHeight="20dip"
android:padding="2dip"
android:progress="50"
android:progressDrawable="@drawable/progress_horizontal1" />

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

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

ok,搞定

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

二)纵向进度条

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


<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270"
/>
</shape>
</clip>
</item>

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


<?xml version="1.0" encoding="utf-8"?>
<clip
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/drawable_resource"
android:clipOrientation=["horizontal" | "vertical"]
android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" |
"fill_vertical" | "center_horizontal" | "fill_horizontal" |
"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


<item android:id="@android:id/progress">
<clip
android:clipOrientation="vertical"
android:gravity = "bottom">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerX="0.75"
android:endColor="#ffffcb00"
android:angle="90"
/>
</shape>
</clip>
</item>

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

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

三)弧形bar

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


  1. public class Arcs extends View {
    private Paint mArcPaint;
    private Paint mArcBGPaint;

    private RectF mOval;
    private float mSweep = 0;
    private int mSpeedMax = 200;
    private int mThreshold = 100;
    private int mIncSpeedValue = 0;
    private int mCurrentSpeedValue = 0;
    private float mCenterX;
    private float mCenterY;
    private float mSpeedArcWidth;

    private final float SPEED_VALUE_INC = 2;

    ..........

    }


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


  1. mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mArcPaint.setStyle(Paint.Style.STROKE);
    mArcPaint.setStrokeWidth(mSpeedArcWidth);
    // mPaint.setStrokeCap(Paint.Cap.ROUND);
    mArcPaint.setColor(0xff81ccd6);
    BlurMaskFilter mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.INNER);
    mArcPaint.setMaskFilter(mBlur);

    mArcBGPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mArcBGPaint.setStyle(Paint.Style.STROKE);
    mArcBGPaint.setStrokeWidth(mSpeedArcWidth+8);
    mArcBGPaint.setColor(0xff171717);

    BlurMaskFilter mBGBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.INNER);
    mArcBGPaint.setMaskFilter(mBGBlur);


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


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


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


  1. @Override
    protected void onDraw(Canvas canvas) {
    drawSpeed(canvas);
    calcSpeed();
    }

    private void drawSpeed(Canvas canvas) {
    canvas.drawArc(mOval, 179, 181, false, mArcBGPaint);

    mSweep = (float) mIncSpeedValue / mSpeedMax * 180;
    if (mIncSpeedValue > mThreshold) {
    mArcPaint.setColor(0xFFFF0000);
    }
    else {
    mArcPaint.setColor(0xFF00B0F0);
    }

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

    private void calcSpeed() {
    if (mIncSpeedValue < mCurrentSpeedValue) {
    mIncSpeedValue += SPEED_VALUE_INC;
    if (mIncSpeedValue > mCurrentSpeedValue) {
    mIncSpeedValue = mCurrentSpeedValue;
    }
    invalidate();
    }
    else if (mIncSpeedValue > mCurrentSpeedValue) {
    mIncSpeedValue -= SPEED_VALUE_INC;
    if (mIncSpeedValue < mCurrentSpeedValue) {
    mIncSpeedValue = mCurrentSpeedValue;
    }
    invalidate();
    }
    }


重写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,大功告成

原文:http://winwyf.blog.51cto.com/4561999/857867

时间: 2024-10-09 13:53:27

Android那些事儿之自定义进度条的相关文章

Android自定义进度条样式

最近在做一个widget,上面需要一个progressbar,产品经理和设计师给出来的东西是要实现一个圆角的progress和自定义的颜色,研究一小下,分享出来给大家哦. 测试于:Android4.0+ 操作步骤: 1.创建你的layout文件引用progressbar如下,标红处引用你自定的样式: <ProgressBar android:id="@+id/progressDownload" style="?android:attr/progressBarStyleH

Android自定义进度条-带文本(文字进度)的水平进度条(ProgressBar)

/** * 带文本提示的进度条 */ public class TextProgressBar extends ProgressBar { private String text; private Paint mPaint; public TextProgressBar(Context context) { super(context); initText(); } public TextProgressBar(Context context, AttributeSet attrs, int d

android 自定义进度条颜色

先看图 基于产品经理各种自定义需求,经过查阅了解,下面是自己对Android自定义进度条的学习过程!   这个没法了只能看源码了,还好下载了源码, sources\base\core\res\res\  下应有尽有,修改进度条颜色只能找progress ,因为是改变样式,首先找styles.xml 找到xml后,进去找到 [html] view plaincopyprint? <span style="font-size: 18px;">    <style name

Android 自定义进度条,

最近工作繁忙,一直都埋头在工作中,也不知这么热心工作究竟是为了什么,不知不觉的,到今天才晓得夏天已经来了.天气热,心也热. 网络上出个牛人,辞职信上写着:世界那么大,我想去看看.由衷的佩服她的勇气,我也想去看看这大千世界,可惜我们总是身不由己,有太多的放不下,或许哪天放下了,我也出去走走. 之前一直以为罗永浩是个逗比,直到前两天看了他几期演讲,才发现逗比一直是我.他有句话我很欣赏,这里也分享给大家:在什么样的年纪,就做什么样的事情,怎么能在每个阶段都做错呢!PS:该玩的年纪玩,该谈恋爱的年纪谈恋

自定义进度条(圆形、横向进度条)

自定义进度条实现大体流程 1.自定义属性声明(attrs文件) 2.自定义属性获取 3.测量(onMeasure) 4.绘制(onDraw) 代码: attrs文件: <!-- 自定义声明 --> <attr name="progress_unreach_color" format="color"></attr> <attr name="progress_unreach_height" format=&q

android113 自定义进度条

MainActivity: package com.itheima.monitor; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.ProgressBar; public class MainActivity extends Activity { private MyProgressBa

自定义进度条\文字描边样式\文字上下滚动TextSwithcher的应用

一.自定义进度条 1.<ProgressBar         android:id="@+id/patch_progress"         style="@style/gxProgressStyle"         android:layout_width="match_parent"         android:layout_height="12dp"         android:layout_alig

自定义进度条PictureProgressBar——从开发到开源发布全过程

自定义进度条PictureProgressBar--从开发到开源发布全过程 出处: 炎之铠邮箱:[email protected] 本文原创,转载请注明本出处! 本项目JCenter地址:https://bintray.com/yanzhikaijky/CustomViewRepository/PictureProgressbar/ 本项目GitHub地址:https://github.com/totond/PictureProgressBar 欢迎 Star or Fork和在Issue里提出

Android常用控件:进度条

各种进度条属于 ProgressBar的子类 Sytle: 水平风格:Horizontal小风格:Small大风格:Large反向风格:Inverse小反向风格:Small.Inverse大反向风格:Large.Inverse 设置style:   style="?android:attr/progressBarStyle..." 主要属性:最大值:max当前进度:progress次要进度值:SecondaryProgress --效果类似于看电影那些缓冲 判断进度条是转圈还是水平的方