progress各种各样的都有,自定义大多数也是简单的,根据业务需求来自己定义,记录一下,先上效果图

自定义Progress小控件

本来想找个第三方改改就上的,不过自己的业务需求有点不搭,一下子没找到合适的,也没这么多时间去找了,想想还是自己写个吧,因为也简单

主要就是需求就是椭圆进度,百分比跟随渐变背景,这样一想其实就是一个布局,然后控制里面的进度长度,或者移动,我这是控制长度,这样毕竟简单,而且扩展好,以后进度条有什么奇葩需求也好改

  1 import android.content.Context;
  2 import android.content.res.TypedArray;
  3 import android.graphics.Color;
  4 import android.support.annotation.AttrRes;
  5 import android.support.annotation.NonNull;
  6 import android.support.annotation.Nullable;
  7 import android.util.AttributeSet;
  8 import android.view.Gravity;
  9 import android.view.View;
 10 import android.view.ViewGroup;
 11 import android.widget.FrameLayout;
 12 import android.widget.TextView;
 13 
 14 import com.app.commonlibrary.R;
 15 
 16 /**
 17  * Created by LiuZhen on 2017/7/8.
 18  */
 19 
 20 public class UpdateProgressBar extends FrameLayout {
 21 
 22     private TextView tv_progress;
 23     private int width;
 24     private ViewGroup.LayoutParams params;
 25     /**
 26      * The progress text offset.
 27      */
 28     private int mOffset;
 29     /**
 30      * The progress text size.
 31      */
 32     private float mTextSize;
 33     /**
 34      * The progress text color.
 35      */
 36     private int mTextColor;
 37     private float default_text_size;
 38     /**
 39      * The progress area bar color.
 40      */
 41     private int mReachedBarColor;
 42     /**
 43      * The bar unreached area color.
 44      */
 45     private int mUnreachedBarColor;
 46     private final int default_reached_color = Color.rgb(66, 145, 241);
 47     private final int default_unreached_color = Color.rgb(204, 204, 204);
 48     private final int default_text_color = Color.rgb(66, 145, 241);
 49 
 50     public UpdateProgressBar(@NonNull Context context) {
 51         this(context,null);
 52     }
 53 
 54     public UpdateProgressBar(@NonNull Context context, @Nullable AttributeSet attrs) {
 55         this(context, attrs,0);
 56     }
 57 
 58     public UpdateProgressBar(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
 59         super(context, attrs, defStyleAttr);
 60         init(attrs, defStyleAttr);
 61     }
 62 
 63     @Override
 64     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 65 
 66         int desiredWidth = 100;
 67         int desiredHeight = 100;
 68 
 69         int widthMode = MeasureSpec.getMode(widthMeasureSpec);
 70         int widthSize = MeasureSpec.getSize(widthMeasureSpec);
 71         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
 72         int heightSize = MeasureSpec.getSize(heightMeasureSpec);
 73 
 74         int height;
 75 
 76         //Measure Width
 77         if (widthMode == MeasureSpec.EXACTLY) {
 78             //Must be this size
 79             width = widthSize;
 80         } else if (widthMode == MeasureSpec.AT_MOST) {
 81             //Can't be bigger than...
 82             width = Math.min(desiredWidth, widthSize);
 83         } else {
 84             //Be whatever you want
 85             width = desiredWidth;
 86         }
 87 
 88         //Measure Height
 89         if (heightMode == MeasureSpec.EXACTLY) {
 90             //Must be this size
 91             height = heightSize;
 92         } else if (heightMode == MeasureSpec.AT_MOST) {
 93             //Can't be bigger than...
 94             height = Math.min(desiredHeight, heightSize);
 95         } else {
 96             //Be whatever you want
 97             height = desiredHeight;
 98         }
 99 
100         int childCount = getChildCount();
101         for (int i = 0; i < childCount; i++) {
102             View child = getChildAt(i);
103             ViewGroup.LayoutParams lp = child.getLayoutParams();
104             int childWidthSpec = getChildMeasureSpec(widthMeasureSpec, 0, lp.width);
105             int childHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0, lp.height);
106             child.measure(childWidthSpec, childHeightSpec);
107         }
108         params = tv_progress.getLayoutParams();
109         params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
110         params.height = ViewGroup.LayoutParams.MATCH_PARENT;
111         tv_progress.setLayoutParams(params);
112         height = tv_progress.getMeasuredHeight();
113         //MUST CALL THIS
114         setMeasuredDimension(width, height);
115     }
116 
117 
118     private void init(AttributeSet attrs, int defStyleAttr){
119 
120         default_text_size = 8;
121         //load styled attributes.
122         final TypedArray attributes = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.UpdateProgressBar,
123                 defStyleAttr, 0);
124 
125         mTextSize = attributes.getDimension(R.styleable.UpdateProgressBar_update_text_size, default_text_size);
126         mReachedBarColor = attributes.getResourceId(R.styleable.UpdateProgressBar_update_reached_color, default_reached_color);
127         mUnreachedBarColor = attributes.getResourceId(R.styleable.UpdateProgressBar_update_unreached_color, default_unreached_color);
128         mTextColor = attributes.getColor(R.styleable.UpdateProgressBar_update_text_color, default_text_color);
129 
130         setDefaultProgressBar();
131 
132         mOffset = px2dip(3);
133 
134         attributes.recycle();
135     }
136 
137     private void setDefaultProgressBar(){
138         setBackgroundResource(mUnreachedBarColor);
139         tv_progress = new TextView(getContext());
140         tv_progress.setTextSize(mTextSize);
141         tv_progress.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);
142         tv_progress.setTextColor(mTextColor);
143         tv_progress.setLines(1);
144         tv_progress.setBackgroundResource(mReachedBarColor);
145         tv_progress.setPadding(dip2px(4),0,dip2px(8),0);
146         tv_progress.setText("0 %");
147         addView(tv_progress);
148     }
149 
150     public void setProgress(int progress){
151         tv_progress.setText(progress+"%");
152         int proWidth = width*progress/100;
153         if (tv_progress.getMeasuredWidth() < proWidth) {
154             //这里不能填充mOffset,因为是椭圆进度条,填充会导致椭圆宽度被进度条覆盖,导致不美观
155 //            tv_progress.setLayoutParams(params);
156             tv_progress.setWidth(proWidth);
157         }
158     }
159 
160     /**
161      * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
162      */
163     public int dip2px(float dpValue) {
164         final float scale = getContext().getResources().getDisplayMetrics().density;
165         return (int) (dpValue * scale + 0.5f);
166     }
167 
168     /**
169      * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
170      */
171     public int px2dip(float pxValue) {
172         final float scale = getContext().getResources().getDisplayMetrics().density;
173         return (int) (pxValue / scale + 0.5f);
174     }
175 
176     /**
177      * 将px值转换为sp值,保证文字大小不变
178      */
179     public int px2sp(float pxValue) {
180         final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
181         return (int) (pxValue / fontScale + 0.5f);
182     }
183 
184     /**
185      * 将sp值转换为px值,保证文字大小不变
186      */
187     public int sp2px(float spValue) {
188         final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
189         return (int) (spValue * fontScale + 0.5f);
190     }
191 
192 }
UpdateProgressBar

相关文章: