Android view自定义带文字带进度的控件

Android view自定义带文字带进度的控件,第1张

概述目标:自定义一个带文字带进度控件,具体内容如下效果图:不孪瓤炊:步骤分析

目标:自定义一个带文字带进度的控件,具体内容如下

效果图:

不孪瓤炊:

步骤分析

提取自定义属性

//提供对外暴露的属性,如有不够自己扩展  <declare-styleable name="DescProgressVIEw">    <attr name="dpv_text_normal_color" format="color" />    <attr name="dpv_text_seleced_color" format="color" />    <attr name="dpv_text_size" format="dimension" />    <attr name="dev_progress_bg_color" format="color" />    <attr name="dev_progress_small_circle_color" format="color" />    <attr name="dev_progress_big_circle_color" format="color" />  </declare-styleable>

解析自定义属性

private voID initAttrs(Context context,@Nullable AttributeSet attrs,int defStyleAttr) {    TypedArray typedArray = context.gettheme().obtainStyledAttributes(attrs,R.styleable.DescProgressVIEw,defStyleAttr,R.style.Def_DescProgressVIEwStyle);    int indexCount = typedArray.getIndexCount();    for (int i = 0; i < indexCount; i++) {      int attr = typedArray.getIndex(i);      switch (attr) {        case R.styleable.DescProgressVIEw_dpv_text_normal_color:          textnormalcolor = typedArray.getcolor(attr,color.BLACK);          break;        case R.styleable.DescProgressVIEw_dpv_text_seleced_color:          textSelectedcolor = typedArray.getcolor(attr,color.BLACK);          break;        case R.styleable.DescProgressVIEw_dpv_text_size:          dpvTextSize = typedArray.getDimensionPixelSize(attr,0);          break;        case R.styleable.DescProgressVIEw_dev_progress_bg_color:          dpvProgressBgcolor = typedArray.getcolor(attr,color.BLACK);          break;        case R.styleable.DescProgressVIEw_dev_progress_small_circle_color:          dpvSmallCiclecolor = typedArray.getcolor(attr,color.BLACK);          break;        case R.styleable.DescProgressVIEw_dev_progress_big_circle_color:          dpvBigCirclecolor = typedArray.getcolor(attr,color.BLACK);          break;      }    }    typedArray.recycle();  }

测量UI图的比例(包含图标大小比例,位置比例)

//这里大家可以根据自己的习惯来,我习惯用vIEw的尺寸当做参照,来约束界面的vIEw,各有利弊,也可以暴露出属性设置具体的dp值,根据比例的话,调整好比例后,所有的绘制内容会统一约束  private static final float SCALE_OF_PROGRESS_HEIGHT = 70.F / 120;  private static final float SCALE_OF_top_AND_BottOM_padding = 10.F / 120;  private static final float SCALE_OF_left_AND_RIGHT_padding = 20.F / 120;  private static final float SCALE_OF_TEXT_DESC_CONTAINER = 50.F / 120;  private static final float SCALE_OF_BIG_CIRCLE_HEIGHT = 22.F / 120;  private static final float SCALE_OF_SMALL_CIRCLE_HEIGHT = 16.F / 120;  private static final float SCALE_OF_liNE_HEIGHT = 4.F / 120;  private static final float DEF_VIEW_HEIGHT = 120.F;

提取绘制的各个元素的位置属性坐标等

这个vIEw的唯一要提前确定的就是文字的位置,文字的位置确定需要知道所有文字的长度,左右间距,计算出中间的白色间隔
代码如下

 /**   * 获取文字在画布中的位置   */  private voID getDescTextRegonPoint() {    for (int i = 0; i < descs.size(); i++) {      Point textRegonPoint = new Point();      int sumX = 0;      //非常重要:计算各个文字在vIEw中的具体坐标,体会下这个二级for循环,子循环是确定每个描述文本的位置      for (int j = 0; j < i; j++) {        Point tempSum = allDescTextPoints.get(j);        sumX += tempSum.x;      }      sumX += i * getTextDescSpace();      textRegonPoint.x = sumX + leftAndRightpadding;      textRegonPoint.y = dpVIEwHeight - topAndBottompadding - textDescContainerHeight / 2;      textPoints4Draw.add(textRegonPoint);    }  }
 /**   * 获取文字的间距   *   * @return 获取文字的间距   */  private float getTextDescSpace() {    float allDescWith = 0;    for (Point tempDesc : allDescTextPoints) {      allDescWith += tempDesc.x;    }    int textContainerW = (int) (dpVIEwWIDth - leftAndRightpadding * 2 - allDescWith);    if (descs != null && descs.size() > 1) {      int spaceCount = descs.size() - 1;      return textContainerW * 1.F / spaceCount;    }    return 0;  }

绘制

我们在vIEw测量确定了尺寸完毕之后,直接绘制即可

 @OverrIDe  protected voID onSizeChanged(int w,int h,int olDW,int oldh) {  // 确定各个比例的大小    super.onSizeChanged(w,h,olDW,oldh);    dpVIEwHeight = h;    dpVIEwWIDth = w;    progressContainerHeight = (int) (SCALE_OF_PROGRESS_HEIGHT * dpVIEwHeight);    topAndBottompadding = (int) (SCALE_OF_top_AND_BottOM_padding * dpVIEwHeight);    leftAndRightpadding = (int) (SCALE_OF_left_AND_RIGHT_padding * dpVIEwHeight);    textDescContainerHeight = (int) (SCALE_OF_TEXT_DESC_CONTAINER * dpVIEwHeight);    smallCircleRadio = (int) (SCALE_OF_SMALL_CIRCLE_HEIGHT * dpVIEwHeight / 2);    bigCircleRadio = (int) (SCALE_OF_BIG_CIRCLE_HEIGHT * dpVIEwHeight / 2);    lineHeight = (int) (SCALE_OF_liNE_HEIGHT * dpVIEwHeight);    // 获取各个部分所需要的约束坐标    getDescTextWIDthAndHeight();    getDescTextRegonPoint();    getBglineRectF();    getBgCirclePoints();    getSelectedRectF();    getcolorFullRectF();    getGrayRectF();  }
@OverrIDe protected voID onDraw(Canvas canvas) {  super.onDraw(canvas);  drawDescText(canvas);  drawBgline(canvas);  drawSelectedline(canvas);  drawGrayRectF(canvas);  drawSelectedCircles(canvas); }//绘制部分的代码就是canvas 的API的使用,没有什么技术含量.//最后暴露给外面设置数据的接口public voID setProgressDescs(List<String> descs,int currentSelectposition) {  this.currentSelectposition = currentSelectposition;  if (descs != null && descs.size() > 1) {   this.descs.clear();   this.descs.addAll(descs);   this.allDescTextPoints.clear();   invalIDate();  } }

源代码下载地址https://github.com/GuoFeilong/DescPbView来个star就更好了谢谢!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android view自定义带文字带进度的控件全部内容,希望文章能够帮你解决Android view自定义带文字带进度的控件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1143784.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存