自定义ProgressBar

原创 2016年06月01日 14:52:38

大家好!由于最近公司需求要求,撸了一晚上,弄出了一个自定义ProgressBar;
废话不多说,看效果!
这里写图片描述
1.看着效果还不错吧!果然不会让大家失望的! 哈哈哈….
这是一个组合控件,首先自定义一个ProgressDragLayout 继承Viewgroup.

public class ProgressDragLayout extends ViewGroup {
    private final String TAG = this.getClass().getSimpleName();
    /**
     * 滑动view 的滑动距离占自身高度的比例
     */
    private double mDrange = 0;
    private ProgressBar pb;
    private ImageView view_mid;
    private TextView view_top;
    private int viewWidth = 1080 - dip2px(getContext(), 40);
    private int size;

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

    public ProgressDragLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ProgressDragLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        view_top = (TextView) findViewById(R.id.view_top);
        view_mid = (ImageView) findViewById(R.id.view_mid);
        pb = (ProgressBar) findViewById(R.id.pb);
    }

并做一些初始化的工作!
2. 丈量VIewGroup 的大小 ,这样我们才能够知道控件大体在view中显示的大小,我们才能够去做一些相关的辅助工作。

 `  /**
     * 丈量所有控件的高度
     * 可以得到每个控件的最终高度
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
        int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
                resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
    }`

3.接下来我们自然要固定Viewgroup中的每个控件的具体位置:

  @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//        Log.e("onLayout", l + "|" + t + "|" + r + "|" + b);
        view_top.layout((int) mDrange + dip2px(getContext(), 20) - view_top.getMeasuredWidth() / 2, t, (int) mDrange + view_top.getMeasuredWidth() / 2 + dip2px(getContext(), 20), view_top.getMeasuredHeight());
        view_mid.layout((int) mDrange + dip2px(getContext(), 20) - view_mid.getMeasuredWidth() / 2, view_top.getMeasuredHeight(), (int) mDrange + view_mid.getMeasuredWidth() / 2 + dip2px(getContext(), 20), view_top.getMeasuredHeight() + view_mid.getMeasuredHeight());
        pb.layout(dip2px(getContext(), 20) + l, view_top.getMeasuredHeight() + view_mid.getMeasuredHeight(), r - dip2px(getContext(), 20), view_top.getMeasuredHeight() + view_mid.getMeasuredHeight() + pb.getMeasuredHeight());
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    private int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

5.固定了具体的位置后,我们接下来就可以进行进度条传值操作的步骤了,下面是该自定义view 的核心部分:

   private int progressAdd = 0;
    private double drange_1 = 0;

    /**
     * RelativeLayout.LayoutParams params_top =  (RelativeLayout.LayoutParams)view_top.getLayoutParams();
     * RelativeLayout.LayoutParams params_mid =  (RelativeLayout.LayoutParams)view_mid.getLayoutParams();
     *
     * @param value
     */
    public void setValue(double value) {
        if(value<=0){
            mDrange = 0;
            pb.setProgress(0);
            ProgressDragLayout.this.requestLayout();
            ProgressDragLayout.this.invalidate();
            return;
        }
        progressAdd = 0;
        mDrange = 0;
        drange_1=0;
        int progress = (int) (value * 100);
        size = progress;
        double drange = (int) (value * viewWidth);
        drange_1 = drange / size;
        Log.e("size-------", size +"");
        mhander.sendEmptyMessageDelayed(view_top.hashCode(),20);
    }
    private Handler mhander = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            progressAdd++;
            mDrange = mDrange +drange_1;
            pb.setProgress(progressAdd);
            view_top.setText(progressAdd + "%");
            ProgressDragLayout.this.requestLayout();
            ProgressDragLayout.this.invalidate();
            Log.e("tag", "progressAdd--" + progressAdd + "|mDrange--" + mDrange);
            if(progressAdd<size){
                mhander.sendEmptyMessageDelayed(view_top.hashCode(),20);
            }
        }
    };

注明下: hander 的工作就是初始化 自定义progressBar 的动画效果!

  1. 接下来贴出完整的代码示例:
package com.example.administrator.myapplication.fragment;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.administrator.myapplication.R;
import com.example.administrator.myapplication.widget.BotomDragLayout;
import com.example.administrator.myapplication.widget.ProgressDragLayout;
import com.example.administrator.myapplication.widget.TopDragLayout;

/**
 * 自定义progressbar
 * 2016/4/21
 */
public class ProgressBarFragment extends Fragment {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getActivity().setTitle("ProgressBarFragment");
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        final ProgressDragLayout view = (ProgressDragLayout) inflater.inflate(R.layout.view_progress_layout, container, false);
        view.setValue(0.8);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

    }
}

完整的 自定义ProgressBarVIew 类:

package com.example.administrator.myapplication.widget;

import android.content.Context;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.administrator.myapplication.R;


/**
 * 自定义progressBar
 * gxj
 */
public class ProgressDragLayout extends ViewGroup {
    private final String TAG = this.getClass().getSimpleName();
    /**
     * 滑动view 的滑动距离占自身高度的比例
     */
    private double mDrange = 0;
    private ProgressBar pb;
    private ImageView view_mid;
    private TextView view_top;
    private int viewWidth = 1080 - dip2px(getContext(), 40);
    private int size;

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

    public ProgressDragLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ProgressDragLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        view_top = (TextView) findViewById(R.id.view_top);
        view_mid = (ImageView) findViewById(R.id.view_mid);
        pb = (ProgressBar) findViewById(R.id.pb);
    }

    private int progressAdd = 0;
    private double drange_1 = 0;

    /**
     * RelativeLayout.LayoutParams params_top =  (RelativeLayout.LayoutParams)view_top.getLayoutParams();
     * RelativeLayout.LayoutParams params_mid =  (RelativeLayout.LayoutParams)view_mid.getLayoutParams();
     *
     * @param value
     */
    public void setValue(double value) {
        if(value<=0){
            mDrange = 0;
            pb.setProgress(0);
            ProgressDragLayout.this.requestLayout();
            ProgressDragLayout.this.invalidate();
            return;
        }
        progressAdd = 0;
        mDrange = 0;
        drange_1=0;
        int progress = (int) (value * 100);
        size = progress;
        double drange = (int) (value * viewWidth);
        drange_1 = drange / size;
        Log.e("size-------", size +"");
        mhander.sendEmptyMessageDelayed(view_top.hashCode(),20);
    }
    private Handler mhander = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            progressAdd++;
            mDrange = mDrange +drange_1;
            pb.setProgress(progressAdd);
            view_top.setText(progressAdd + "%");
            ProgressDragLayout.this.requestLayout();
            ProgressDragLayout.this.invalidate();
            Log.e("tag", "progressAdd--" + progressAdd + "|mDrange--" + mDrange);
            if(progressAdd<size){
                mhander.sendEmptyMessageDelayed(view_top.hashCode(),20);
            }
        }
    };

    /**
     * 丈量所有控件的高度
     * 可以得到每个控件的最终高度
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
        int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
                resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//        Log.e("onLayout", l + "|" + t + "|" + r + "|" + b);
        view_top.layout((int) mDrange + dip2px(getContext(), 20) - view_top.getMeasuredWidth() / 2, t, (int) mDrange + view_top.getMeasuredWidth() / 2 + dip2px(getContext(), 20), view_top.getMeasuredHeight());
        view_mid.layout((int) mDrange + dip2px(getContext(), 20) - view_mid.getMeasuredWidth() / 2, view_top.getMeasuredHeight(), (int) mDrange + view_mid.getMeasuredWidth() / 2 + dip2px(getContext(), 20), view_top.getMeasuredHeight() + view_mid.getMeasuredHeight());
        pb.layout(dip2px(getContext(), 20) + l, view_top.getMeasuredHeight() + view_mid.getMeasuredHeight(), r - dip2px(getContext(), 20), view_top.getMeasuredHeight() + view_mid.getMeasuredHeight() + pb.getMeasuredHeight());
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    private int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

最后附上demo的下载地址 : 猛戳这里–https://github.com/g1258624735/MyApplication2
5. 所有的代码已经全部上传,注释很详细,包你看懂,已经详细的不能在详细了,看不懂的可以板砖拍我。
6. 大家在看的过程 当中,如果有什么不懂得话可以发邮件给我 ,1258624735@qq.com
7. ps: 如果大家觉得文章对你有帮助:不妨大赏一下支持原创,你的支持是我最大的动力:这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。

自定义简单ProgressBar样式

该篇为学习笔记 记录学习中的困难,日后便于回顾熟练。 为了毕业找工作,决定基于环信的SDK,开发一个能发送多种消息类型的聊天应用。 第一步,想得有个欢迎界面,初始化界面。 由于android自...
  • Star_SDK
  • Star_SDK
  • 2017年03月07日 19:32
  • 1804

Android progressBar 自定义

在drawable文件夹中建立如下旋转动画文件     android:drawable="@drawable/loading1"         android:pivotX="50%"   ...
  • fancylovejava
  • fancylovejava
  • 2014年03月19日 20:53
  • 21477

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

出处: 炎之铠邮箱:yanzhikai_yjk@qq.com 本文原创,转载请注明本出处! 本项目JCenter地址:https://bintray.com/yanzhikaijky...
  • totond
  • totond
  • 2017年05月17日 11:10
  • 5370

android 自定义水平的ProgressBar

android 自定义水平的ProgressBar 颜色
  • u011140027
  • u011140027
  • 2013年10月16日 17:44
  • 2128

Android 自定义横向的ProgressBar的颜色

1、首先在Drawable下面新建一个
  • laotai909101
  • laotai909101
  • 2014年06月18日 18:05
  • 1122

Android 自定义ProgressBar样式

首先,在activity_main中定义个一个ProgressBar 控件
  • qq_33048603
  • qq_33048603
  • 2016年07月08日 11:06
  • 548

Android中自定义水平的ProgressBar

自定义水平ProgressBar
  • newMan1024
  • newMan1024
  • 2017年11月07日 10:50
  • 116

自定义旋转的ProgressBar

自定义圆环
  • u010217620
  • u010217620
  • 2016年01月31日 09:07
  • 594

Android 自定义Progressbar,任何图片都能当成progressbar转动起来

今天群里边有人问怎么自定义Android holo主题下的Progressbar; 我想到之前做过自定义Progressbar,通过自己写动画和Style可以用任何图片当作progressbar来转动...
  • sweetvvck
  • sweetvvck
  • 2014年04月16日 22:44
  • 5754

Android自定义view之ProgressBar的实现

在学习自定义view之前我们必须先来了解一下attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性,因此在自定义控件属性的时候,创建一个attrs.xml...
  • qq_17475155
  • qq_17475155
  • 2016年05月25日 19:57
  • 937
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义ProgressBar
举报原因:
原因补充:

(最多只允许输入30个字)