资讯专栏INFORMATION COLUMN

自定义ProgressBar(自定义View和ClipDrawable)

spademan / 3265人阅读

摘要:第二个参数图片,第三个参数开始裁剪的位置,这里是从左开始布局中使用,和普通的使用方法一样最后是代码中的的引用取值不可见,完全显示这样复杂的可以直接使用图片按比例显示读取进度节省代码量

开发中经常需要自定义ProgressBar,这里用了自定义View和ClipDrawable实现简单的ProgressBar
自定义View效果:

public class CustomProgressBar extends View {

    private Paint mBgtPaint;//底部背景画笔
    private Paint mProgressPaint;//progress画笔
    private int startX;//起始X坐标,保持不变
    private int endX;//终点坐标,保持不变
    private int currentX;//当前坐标,progress换算而来,不断增大

    private int mProgressBgHeight = 60;
    private int mProgressHeight = 50;
    private int mProgressBgColor = Color.BLACK;
    private int mProgressColor = Color.BLUE;

    public CustomProgressBar(Context context){
        this(context, null);
    }

    public CustomProgressBar(Context context, @Nullable AttributeSet attrs){
       this(context, attrs, 0);

    }

    public CustomProgressBar(Context context,  @Nullable AttributeSet attrs, int defStyleAttr){
        super(context, attrs, defStyleAttr);

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                R.styleable.myProgressBar, defStyleAttr, 0);

        mProgressBgHeight = a.getInteger(R.styleable.myProgressBar_progress_background_height, mProgressBgHeight);
        mProgressHeight = a.getInteger(R.styleable.myProgressBar_progress_height,mProgressHeight);

        mProgressBgColor = a.getColor(R.styleable.myProgressBar_progress_background_color,mProgressBgColor);
        mProgressColor = a.getColor(R.styleable.myProgressBar_progress_color, mProgressColor);

        a.recycle();

        init();
    }


    private void init() {

        //初始化画笔
        mBgtPaint = new Paint();
        mBgtPaint.setAntiAlias(true);//抗锯齿
        mBgtPaint.setStyle(Paint.Style.STROKE);
        //注意:这是笔尖样式的属性,Paint.Cap.ROUND设置笔尖为圆形,默认方形,
        mBgtPaint.setStrokeCap(Paint.Cap.ROUND);
        mBgtPaint.setColor(mProgressBgColor);
//        mBgtPaint.setColor(Color.parseColor("#1F1F26"));//设置画笔颜色,这里是深灰色
        mBgtPaint.setStrokeWidth(60);

        mProgressPaint = new Paint();
        mProgressPaint.setAntiAlias(true);
        mProgressPaint.setStyle(Paint.Style.STROKE);
        mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
        mProgressPaint.setColor(mProgressColor);
//        mProgressPaint.setColor(Color.parseColor("#54FC00"));
        mProgressPaint.setStrokeWidth(50);//这里的线条宽度比背景线条窄一些。

    }


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        //这里根据屏幕的宽高获取坐标,可以设置成自定义属性,让用户设置
        startX = getWidth()/2-getWidth()/3;
        endX = getWidth()/2 + getWidth()/3;
        currentX = startX;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //绘制底部背景线条(深灰色,区别于View背景色)
        canvas.drawLine(startX, getHeight() / 2, endX,
                getHeight() / 2, mBgtPaint);

        //绘制当前的progress
        canvas.drawLine(startX+1, getHeight() / 2, currentX,
                getHeight() / 2, mProgressPaint);

    }

    //更新进度
    public void updateProgress(int progress) {

        //这里progress的长度分成100个单位,再计算坐标,其实progress可以是实时的下载进度,
        //计算下载量百分比,然后再计算坐标,会相对精确
        if (progress <= 100){
            currentX = startX + (int)((progress * 1.0)/100 * (endX - startX));
            invalidate();//重新绘制才能生效
        }
    }
}

使用到了自定义的属性,可以在values/下添加attrs.xml(文件可以为其他名字),res/values/attrs.xml



    

        
        
        
        
    

代码中使用:

public class CustomActivity extends AppCompatActivity {


    private CustomProgressBar mCustomProgressBar;

    private int mProgress=0;

    private Handler mHandler = new Handler();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom);

        mCustomProgressBar = (CustomProgressBar)findViewById(R.id.progress_bar_custom);

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {

                mCustomProgressBar.updateProgress(++mProgress);
                if (mProgress < 100) {
                    mHandler.postDelayed(this, 500);
                }
            }
        }, 500);

    }
}

这样大部分的自定义的ProgressBar都可以画出来,有些可能需要添加动画。如果有些ProgressBar本身的样式
太过复杂,使用自定义view画出来有较大的难度,那么还有更简单的方法,让ui切出ProgressBar完整的图片,然后使用ClipDrawable根据
进度的更新不断地显示,使用起来其实挺简单的,效果图:

先定义一个clipDrawable



第一个属性:裁剪方向,这里是水平方向。第二个参数:图片,第三个参数:开始裁剪的位置,这里是从左开始

xml布局中使用,和普通的drawable使用方法一样




    


最后是代码中的的引用

public class ClipDrawableActivity extends AppCompatActivity {

    private Handler mHandler = new Handler();
    private int mLevel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_clip_drawable);

        ImageView imageView = (ImageView)findViewById(R.id.img_clip);

        final ClipDrawable clipDrawable = (ClipDrawable)imageView.getDrawable();

        //level取值:0-10000, 0:不可见,10000:完全显示
        mLevel = clipDrawable.getLevel();

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                clipDrawable.setLevel(mLevel);
                mLevel += 100;

                if (mLevel <= 10000) {
                    mHandler.postDelayed(this, 500);
                }
            }
        }, 500);

    }
}

这样复杂的ProgressBar, 可以直接使用图片按比例显示读取进度,节省代码量.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/14022.html

相关文章

  • QQ运动步数&定义ProgressBar

    摘要:效果如下图展示效果不好,实际体验无卡顿自定义属性早目录下,命名为命名随意,但规范命名为自定义属性如下,注意不要与自带的命名重复。效果如下 gif图展示效果不好,实际体验无卡顿 1.自定义属性 早Values目录下New-values resource file,命名为attrs.xml(命名随意,但规范命名为attrs.xml) 自定义属性如下,注意format不要与Andr...

    plokmju88 评论0 收藏0
  • 基于 HTML5 的 3D 工业互联网展示方案

    摘要:自定义类继承了布局组件,此布局器将自身空间划分为上下左右中间五个区域,每个区域可以放置一个子组件。 前言 通用电气(GE)、IBM、英特尔等公司主推的工业互联网正在经历产品-数据分析平台-应用-生态的演进。这主要得益于 Predix 数据分析平台对工业互联网应用的整合能力。Predix 就像工业数据领域的 iOS 或者安卓系统一样,能够让工程师自己建立模型和应用,打通前方数以万计的传感...

    HmyBmny 评论0 收藏0
  • 基于 HTML5 WebGL 的 3D 仓储管理系统

    摘要:自定义类继承了布局组件,此布局器将自身空间划分为上下左右中间五个区域,每个区域可以放置一个子组件。 仓储管理系统(WMS)是一个实时的计算机软件系统,它能够按照运作的业务规则和运算法则,对信息、资源、行为、存货和分销运作进行更完美地管理,使其最大化满足有效产出和精确性的要求。从财务软件、进销存软件CIMS,从MRP、MRPII到ERP,代表了中国企业从粗放型管理走向集约管理的要求,竞争...

    SmallBoyO 评论0 收藏0
  • 【腾讯Bugly干货分享】Android动态布局入门及NinePatchChunk解密

    摘要:使用定义布局的方式,有着结构清晰可预览等优势,因而极为通用。可是,偏偏在某些场景下,布局是需要根据运行时的状态变化的,无法使用预先定义。这时候,我们只能通过控制,在程序运行时,动态的实现对应的布局。这是动态布局中最基础最常用的步骤。 本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57c7f... 作者:黄进——QQ...

    leanxi 评论0 收藏0
  • 简易仿ios菊花加载loading图

    摘要:原文链接项目中经常会用到加载数据的显示图,除了设计根据自身设计的动画,一般用的比较多的是仿照的菊花加载图,当然一些条件下还会涉及到加载成功失败情况的显示,还有显示文字。使用来加载动画转圈,这里使用文件定义转圈动画,属性进行加载。 原文链接:https://mp.weixin.qq.com/s/wBbQgOfr59wntNK9ZJ5iRw 项目中经常会用到加载数据的loading显示图...

    崔晓明 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<