Android自定义View实现水平带数字百分比进度条

发布时间:2019-08-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Android自定义View实现水平带数字百分比进度条脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

这个进度条可以反映真实进度,并且完成百分比的文字时随着进度增加而移动的,所在位置也恰好是真实完成的百分比位置,效果如下:

Android自定义View实现水平带数字百分比进度条

思路如下:第一部分是左侧的蓝色直线,代表已经完成的进度;第二部分是右侧灰色的直线,代表未完成的进度;第三部分是红色的百分比的数字百分比文本,显示当前确切的完成进度。

最关键的部分就是要确定百分比文本的确切位置,这里用了paint的getTextBounds方法,得到文本的高,然后再精确确定它的位置。

view代码如下:

 public class NumberPRogressView extends View {     /**    * 进度条画笔的宽度(dp)    */   private int paintProgressWidth = 3;     /**    * 文字百分比的字体大小(sp)    */   private int paintTextSize = 20;     /**    * 左侧已完成进度条的颜色    */   private int paintLeftColor = 0xff67aae4;     /**    * 右侧未完成进度条的颜色    */   private int paintRightColor = 0xffaaaaaa;     /**    * 百分比文字的颜色    */   private int paintTextColor = 0xffff0077;     /**    * Contxt    */   private Context context;     /**    * 主线程传过来进程 0 - 100    */   private int progress;     /**    * 得到自定义视图的宽度    */   private int viewWidth;     /**    * 得到自定义视图的Y轴中心点    */   private int viewcenterY;     /**    * 画左边已完成进度条的画笔    */   private Paint paintleft = new Paint();     /**    * 画右边未完成进度条的画笔    */   private Paint paintRight = new Paint();     /**    * 画中间的百分比文字的画笔    */   private Paint paintText = new Paint();     /**    * 要画的文字的宽度    */   private int textWidth;     /**    * 画文字时底部的坐标    */   private float textBottomY;     /**    * 包裹文字的矩形    */   private Rect rect = new Rect();     /**    * 文字总共移动的长度(即从0%到100%文字左侧移动的长度)    */   private int totalMovedLength;     public NumberProgressView(Context context, AttributeSet attrs) {     suPEr(context, attrs);     this.context = context;     // 构造器中初始化数据     inITData();   }     /**    * 初始化数据    */   private void initData() {       //设置进度条画笔的宽度     int paintProgressWidthPx = Utils.dip2px(context, paintProgressWidth);       //设置百分比文字的尺寸     int paintTextSizePx = Utils.sp2px(context, paintTextSize);       // 已完成进度条画笔的属性     paintleft.setColor(paintLeftColor);     paintleft.setstrokeWidth(paintProgressWidthPx);     paintleft.setAntiAlias(true);     paintleft.setStyle(Style.FILL);       // 未完成进度条画笔的属性     paintRight.setColor(paintRightColor);     paintRight.setStrokeWidth(paintProgressWidthPx);     paintRight.setAntiAlias(true);     paintRight.setStyle(Style.FILL);       // 百分比文字画笔的属性     paintText.setColor(paintTextColor);     paintText.setTextSize(paintTextSizePx);     paintText.setAntiAlias(true);     paintText.setTypeface(Typeface.DEFAULT_BOLD);     }     @override   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {     super.onMeasure(widthMeasureSpec, heightMeasureSpec);     getWidthAndHeight();   }     /**    * 得到视图等的高度宽度尺寸数据    */   private void getWidthAndHeight() {       //得到包围文字的矩形的宽高     paintText.getTextBounds("000%", 0, "000%".length(), rect);     textWidth = rect.width();     textBottomY = viewCenterY + rect.height() / 2;       //得到自定义视图的高度     int viewHeight = getMeasuredHeight();     viewWidth = getMeasuredWidth();     viewCenterY = viewHeight / 2;     totalMovedLength = viewWidth - textWidth;     }     @Override   protected void onDraw(Canvas canvas) {     super.onDraw(canvas);       //得到float型进度     float progressFloat = progress / 100.0f;       //当前文字移动的长度     float currentMovedLentgh = totalMovedLength * progressFloat;       //画左侧已经完成的进度条,长度为从Veiw左端到文字的左侧     canvas.drawLine(0, viewCenterY, currentMovedLentgh, viewCenterY, paintleft);       //画右侧未完成的进度条,这个进度条的长度不是严格按照百分比来缩放的,因为文字的长度会变化,所以它的长度缩放比例也会变化     if (progress < 10) {       canvas.drawLine(currentMovedLentgh + textWidth * 0.5f, viewCenterY, viewWidth, viewCenterY, paintRight);     } else if (progress < 100) {       canvas.drawLine(currentMovedLentgh + textWidth * 0.75f, viewCenterY, viewWidth, viewCenterY, paintRight);     } else {       canvas.drawLine(currentMovedLentgh + textWidth, viewCenterY, viewWidth, viewCenterY, paintRight);     }       //画文字(注意:文字要最后画,因为文字和进度条可能会有重合部分,所以要最后画文字,用文字盖住重合的部分)     canvas.drawText(progress + "%", currentMovedLentgh, textBottomY, paintText);   }     /**    * @param progress 外部传进来的当前进度    */   public void setProgress(int progress) {     this.progress = progress;     invalidate();   } }

调用者activity的代码,设置进度条的进度:

 public class NumberProgressBarActivity extends Activity {     protected static final int What_INCREASE = 1;   private NumberProgressView np_numberProgressBar;   private int progress;     private Handler handler = new Handler() {     public void handleMessage(andROId.os.Message msg) {       progress++;       np_numberProgressBar.setProgress(progress);       handler.sendEmptyMessageDelayed(WHAT_INCREASE, getRadomNumber(50, 200));       if (progress >= 100) {         handler.removeMessages(WHAT_INCREASE);       }     }   };     @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_number_progress_bar);     np_numberProgressBar = (NumberProgressView) findViewById(R.id.np_numberProgressBar);     Button BTn_numberProgressBar = (Button) findViewById(R.id.btn_numberProgressBar);     btn_numberProgressBar.setOnClickListener(new OnClickListener() {       @Override       public void onClick(View v) {         increase();       }     });   }     private void increase() {     progress = 0;     np_numberProgressBar.setProgress(0);     handler.removeMessages(WHAT_INCREASE);     handler.sendEmptyMessage(WHAT_INCREASE);   }     /**    * 得到两个整数之间的一个随机数    *    * @param start 较小的数    * @param end  较大的数    * @return    */   public int getRadomNumber(int start, int end) {     return (int) (start + Math.random() * (end - start));   } }

工具方法:

 /**    * 将dip或dp值转换为px值,保证尺寸大小不变    */   public static int dip2px(Context context, float dipvalue) {     final float scale = context.getResources().getDisplayMetrics().density;     return (int) (dipValue * scale + 0.5f);   }     /**    * 将sp值转换为px值,保证文字大小不变    */   public static int sp2px(Context context, float spValue) {     final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;     return (int) (spValue * fontScale + 0.5f);   }

布局:

 <LinearLayout XMlns:android="http://schemas.android.COM/apk/res/android"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical">     <com.example.viewdemo.view.NumberProgressView     android:id="@+id/np_numberProgressBar"     android:layout_width="wrap_content"     android:layout_height="100dp"     android:layout_margin="20dp"     android:background="#33890075"     />     <Button     android:id="@+id/btn_numberProgressBar"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:text="开始"/>   </LinearLayout>
android教程
脚本网站
android studio

脚本宝典总结

以上是脚本宝典为你收集整理的Android自定义View实现水平带数字百分比进度条全部内容,希望文章能够帮你解决Android自定义View实现水平带数字百分比进度条所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。