欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 仿摩拜单车共享单车进度条实现StepView效果

程序员文章站 2023-12-05 12:49:16
先看效果图: step1:定义stepbean 定义五个状态,分别为:为完成、正在进行、已完成、终点完成、终点未完成。 public class step...

先看效果图:

Android 仿摩拜单车共享单车进度条实现StepView效果

step1:定义stepbean

定义五个状态,分别为:为完成、正在进行、已完成、终点完成、终点未完成。

public class stepbean{
  public static final int step_undo = -1;//未完成
  public static final int step_current = 0;//正在进行
  public static final int step_completed = 1;//已完成
  public static final int step_last_completed = 2;//终点完成
  public static final int step_last_uncompleted = 3;//终点未完成
  private string name;
  private int state;
  public string getname(){
    return name;
  }
  public void setname(string name){
    this.name = name;
  }
  public int getstate(){
    return state;
  }
  public void setstate(int state){
    this.state = state;
  }
  public stepbean(){
  }
  public stepbean(string name, int state){
    this.name = name;
    this.state = state;
  }
}

step2:自定义horizontalstepsviewindicator

public class horizontalstepsviewindicator extends view {
  private int defaultstepindicatornum = (int) typedvalue.applydimension(typedvalue.complex_unit_dip, 40, getresources().getdisplaymetrics());//定义默认的高度
  private float mcompletedlineheight;//完成线的高度
  private float mcircleradius;//圆的半径
  private drawable mcompleteicon;//完成的默认图片
  private drawable mattentionicon;//正在进行的默认图片
  private drawable mdefaulticon;//默认的背景图
  private drawable mlastcompleteicon;//终点未完成图片
  private drawable mlastuncompleteicon;//终点完成图片
  private float mcentery;//该view的y轴中间位置
  private float mlefty;//左上方的y位置
  private float mrighty;//右下方的位置
  private list<stepbean> mstepbeanlist ;//当前有几步流程
  private int mstepnum = 0;
  private float mlinepadding;//两条连线之间的间距
  private list<float> mcirclecenterpointpositionlist;//定义所有圆的圆心点位置的集合
  private paint muncompletedpaint;//未完成paint
  private paint mcompletedpaint;//完成paint
  private int muncompletedlinecolor = contextcompat.getcolor(getcontext(), r.color.uncompleted_color);//定义默认未完成线的颜色
  private int mcompletedlinecolor = contextcompat.getcolor(getcontext(), r.color.completed_color);//定义默认完成线的颜色
  private patheffect meffects;
  private int mcomplectingposition;//正在进行position
  private path mpath;
  private ondrawindicatorlistener mondrawlistener;
  private int screenwidth;
  /**
   * 设置监听
   * @param ondrawlistener
   */
  public void setondrawlistener(ondrawindicatorlistener ondrawlistener){
    mondrawlistener = ondrawlistener;
  }
  /**
   * get圆的半径 get circle radius
   * @return
   */
  public float getcircleradius(){
    return mcircleradius;
  }
  public horizontalstepsviewindicator(context context){
    this(context, null);
  }
  public horizontalstepsviewindicator(context context, attributeset attrs){
    this(context, attrs, 0);
  }
  public horizontalstepsviewindicator(context context, attributeset attrs, int defstyle){
    super(context, attrs, defstyle);
    init();
  }
  private void init(){
    mstepbeanlist = new arraylist<>();
    mpath = new path();
    meffects = new dashpatheffect(new float[]{8, 8, 8, 8}, 1);
    mcirclecenterpointpositionlist = new arraylist<>();//初始化
    muncompletedpaint = new paint();
    mcompletedpaint = new paint();
    muncompletedpaint.setantialias(true);
    muncompletedpaint.setcolor(muncompletedlinecolor);
    muncompletedpaint.setstyle(paint.style.stroke);
    muncompletedpaint.setstrokewidth(2);
    mcompletedpaint.setantialias(true);
    mcompletedpaint.setcolor(mcompletedlinecolor);
    mcompletedpaint.setstyle(paint.style.stroke);
    mcompletedpaint.setstrokewidth(2);
    muncompletedpaint.setpatheffect(meffects);
    mcompletedpaint.setstyle(paint.style.fill);
    mcompletedlineheight = 0.03f * defaultstepindicatornum;//已经完成线的宽高
    mcircleradius = 0.28f * defaultstepindicatornum;//圆的半径
    mlinepadding = 1.0f * defaultstepindicatornum;//线与线之间的间距
    mcompleteicon = contextcompat.getdrawable(getcontext(), r.drawable.complted);//已经完成的icon
    mattentionicon = contextcompat.getdrawable(getcontext(), r.drawable.attention);//正在进行的icon
    mdefaulticon = contextcompat.getdrawable(getcontext(), r.drawable.default_icon);//未完成的icon
    mlastcompleteicon= contextcompat.getdrawable(getcontext(), r.drawable.last_complted);//终点已完成的icon
    mlastuncompleteicon= contextcompat.getdrawable(getcontext(), r.drawable.last_uncomplted);//终点未完成的icon
  }
  @override
  protected synchronized void onmeasure(int widthmeasurespec, int heightmeasurespec){
    int width = defaultstepindicatornum * 2;
    if(measurespec.unspecified != measurespec.getmode(widthmeasurespec)){
      screenwidth = measurespec.getsize(widthmeasurespec);
    }
    int height = defaultstepindicatornum;
    if(measurespec.unspecified != measurespec.getmode(heightmeasurespec)){
      height = math.min(height, measurespec.getsize(heightmeasurespec));
    }
    width = (int) (mstepnum * mcircleradius * 2 - (mstepnum - 1) * mlinepadding);
    setmeasureddimension(width, height);
  }
  @override
  protected void onsizechanged(int w, int h, int oldw, int oldh){
    super.onsizechanged(w, h, oldw, oldh);
    //获取中间的高度,目的是为了让该view绘制的线和圆在该view垂直居中
    mcentery = 0.5f * getheight();
    //获取左上方y的位置,获取该点的意义是为了方便画矩形左上的y位置
    mlefty = mcentery - (mcompletedlineheight / 2);
    //获取右下方y的位置,获取该点的意义是为了方便画矩形右下的y位置
    mrighty = mcentery + mcompletedlineheight / 2;
    mcirclecenterpointpositionlist.clear();
    for(int i = 0; i < mstepnum; i++){
      //先计算全部最左边的padding值(getwidth()-(圆形直径+两圆之间距离)*2)
      float paddingleft = (screenwidth - mstepnum * mcircleradius * 2 - (mstepnum - 1) * mlinepadding) / 2;
      //add to list
      mcirclecenterpointpositionlist.add(paddingleft + mcircleradius + i * mcircleradius * 2 + i * mlinepadding);
    }
    /**
     * set listener
     */
    if(mondrawlistener!=null){
      mondrawlistener.ondrawindicator();
    }
  }
  @override
  protected synchronized void ondraw(canvas canvas){
    super.ondraw(canvas);
    if(mondrawlistener!=null){
      mondrawlistener.ondrawindicator();
    }
    muncompletedpaint.setcolor(muncompletedlinecolor);
    mcompletedpaint.setcolor(mcompletedlinecolor);
    //-----------------------画线-------draw line-----------------------------------------------
    for(int i = 0; i < mcirclecenterpointpositionlist.size() -1; i++){
      //前一个complectedxposition
      final float precomplectedxposition = mcirclecenterpointpositionlist.get(i);
      //后一个complectedxposition
      final float aftercomplectedxposition = mcirclecenterpointpositionlist.get(i + 1);
      if(i <= mcomplectingposition&&mstepbeanlist.get(0).getstate()!=stepbean.step_undo){//判断在完成之前的所有点
        //判断在完成之前的所有点,画完成的线,这里是矩形,很细的矩形,类似线,为了做区分,好看些
        canvas.drawrect(precomplectedxposition + mcircleradius - 10, mlefty, aftercomplectedxposition - mcircleradius + 10, mrighty, mcompletedpaint);
      } else{
        mpath.moveto(precomplectedxposition + mcircleradius, mcentery);
        mpath.lineto(aftercomplectedxposition - mcircleradius, mcentery);
        canvas.drawpath(mpath, muncompletedpaint);
      }
    }
    //-----------------------画线-------draw line-----------------------------------------------
    //-----------------------画图标-----draw icon-----------------------------------------------
    for(int i = 0; i < mcirclecenterpointpositionlist.size(); i++){
      final float currentcomplectedxposition = mcirclecenterpointpositionlist.get(i);
      rect rect = new rect((int) (currentcomplectedxposition - mcircleradius), (int) (mcentery - mcircleradius), (int) (currentcomplectedxposition + mcircleradius), (int) (mcentery + mcircleradius));
      stepbean stepsbean = mstepbeanlist.get(i);
      if(stepsbean.getstate()==stepbean.step_undo){
        mdefaulticon.setbounds(rect);
        mdefaulticon.draw(canvas);
      }else if(stepsbean.getstate()==stepbean.step_current){
        mcompletedpaint.setcolor(color.white);
        canvas.drawcircle(currentcomplectedxposition, mcentery, mcircleradius * 1.1f, mcompletedpaint);
        mattentionicon.setbounds(rect);
        mattentionicon.draw(canvas);
      }else if(stepsbean.getstate()==stepbean.step_completed){
        mcompleteicon.setbounds(rect);
        mcompleteicon.draw(canvas);
      }else if(stepsbean.getstate()==stepbean.step_last_completed){
        mlastcompleteicon.setbounds(rect);
        mlastcompleteicon.draw(canvas);
      }else if(stepsbean.getstate()==stepbean.step_last_uncompleted){
        mlastuncompleteicon.setbounds(rect);
        mlastuncompleteicon.draw(canvas);
      }
    }
    //-----------------------画图标-----draw icon-----------------------------------------------
  }
  /**
   * 得到所有圆点所在的位置
   * @return
   */
  public list<float> getcirclecenterpointpositionlist()
  {
    return mcirclecenterpointpositionlist;
  }
  /**
   * 设置流程步数
   * @param stepsbeanlist 流程步数
   */
  public void setstepnum(list<stepbean> stepsbeanlist) {
    this.mstepbeanlist = stepsbeanlist;
    mstepnum = mstepbeanlist.size();
    if(mstepbeanlist!=null&&mstepbeanlist.size()>0){
      for(int i = 0;i<mstepnum;i++){
        stepbean stepsbean = mstepbeanlist.get(i);
          if(stepsbean.getstate()==stepbean.step_completed){
            mcomplectingposition = i;
          }
      }
    }
    requestlayout();
  }
  /**
   * 设置未完成线的颜色
   * @param uncompletedlinecolor
   */
  public void setuncompletedlinecolor(int uncompletedlinecolor){
    this.muncompletedlinecolor = uncompletedlinecolor;
  }
  /**
   * 设置已完成线的颜色
   * @param completedlinecolor
   */
  public void setcompletedlinecolor(int completedlinecolor){
    this.mcompletedlinecolor = completedlinecolor;
  }
  /**
   * 设置默认图片
   * @param defaulticon
   */
  public void setdefaulticon(drawable defaulticon){
    this.mdefaulticon = defaulticon;
  }
  /**
   * 设置已完成图片
   * @param completeicon
   */
  public void setcompleteicon(drawable completeicon){
    this.mcompleteicon = completeicon;
  }
  public void setlastcompleteicon(drawable lastcompleteicon){
    this.mlastcompleteicon = lastcompleteicon;
  }
  public void setlastuncompleteicon(drawable lastuncompleteicon){
    this.mlastuncompleteicon = lastuncompleteicon;
  }
  /**
   * 设置正在进行中的图片
   * @param attentionicon
   */
  public void setattentionicon(drawable attentionicon){
    this.mattentionicon = attentionicon;
  }
  /**
   * 设置对view监听
   */
  public interface ondrawindicatorlistener{
    void ondrawindicator();
  }
}

step3:自定义horizontalstepview

public class horizontalstepview extends linearlayout implements horizontalstepsviewindicator.ondrawindicatorlistener{
  private relativelayout mtextcontainer;
  private horizontalstepsviewindicator mstepsviewindicator;
  private list<stepbean> mstepbeanlist;
  private int mcomplectingposition;
  private int muncomplectedtextcolor = contextcompat.getcolor(getcontext(), r.color.uncompleted_text_color);//定义默认未完成文字的颜色;
  private int mcomplectedtextcolor = contextcompat.getcolor(getcontext(), r.color.completed_color);//定义默认完成文字的颜色;
  private int mtextsize = 14;//default textsize
  private textview mtextview;
  public horizontalstepview(context context){
    this(context, null);
  }
  public horizontalstepview(context context, attributeset attrs){
    this(context, attrs, 0);
  }
  public horizontalstepview(context context, attributeset attrs, int defstyleattr){
    super(context, attrs, defstyleattr);
    init();
  }
  private void init(){
    view rootview = layoutinflater.from(getcontext()).inflate(r.layout.widget_horizontal_stepsview, this);
    mstepsviewindicator = (horizontalstepsviewindicator) rootview.findviewbyid(r.id.steps_indicator);
    mstepsviewindicator.setondrawlistener(this);
    mtextcontainer = (relativelayout) rootview.findviewbyid(r.id.rl_text_container);
  }
  /**
   * 设置显示的文字
   * @param stepsbeanlist
   * @return
   */
  public horizontalstepview setstepviewtexts(list<stepbean> stepsbeanlist) {
    mstepbeanlist = stepsbeanlist;
    mstepsviewindicator.setstepnum(mstepbeanlist);
    return this;
  }
  /**
   * 设置未完成文字的颜色
   * @param uncomplectedtextcolor
   * @return
   */
  public horizontalstepview setstepviewuncomplectedtextcolor(int uncomplectedtextcolor) {
    muncomplectedtextcolor = uncomplectedtextcolor;
    return this;
  }
  /**
   * 设置完成文字的颜色
   * @param complectedtextcolor
   * @return
   */
  public horizontalstepview setstepviewcomplectedtextcolor(int complectedtextcolor) {
    this.mcomplectedtextcolor = complectedtextcolor;
    return this;
  }
  /**
   * 设置stepsviewindicator未完成线的颜色
   * @param uncompletedlinecolor
   * @return
   */
  public horizontalstepview setstepsviewindicatoruncompletedlinecolor(int uncompletedlinecolor) {
    mstepsviewindicator.setuncompletedlinecolor(uncompletedlinecolor);
    return this;
  }
  /**
   * 设置stepsviewindicator完成线的颜色
   * @param completedlinecolor
   * @return
   */
  public horizontalstepview setstepsviewindicatorcompletedlinecolor(int completedlinecolor) {
    mstepsviewindicator.setcompletedlinecolor(completedlinecolor);
    return this;
  }
  /**
   * 设置stepsviewindicator默认图片
   * @param defaulticon
   */
  public horizontalstepview setstepsviewindicatordefaulticon(drawable defaulticon) {
    mstepsviewindicator.setdefaulticon(defaulticon);
    return this;
  }
  /**
   * 设置stepsviewindicator已完成图片
   * @param completeicon
   */
  public horizontalstepview setstepsviewindicatorcompleteicon(drawable completeicon) {
    mstepsviewindicator.setcompleteicon(completeicon);
    return this;
  }
  /**
   * 设置stepsviewindicator正在进行中的图片
   * @param attentionicon
   */
  public horizontalstepview setstepsviewindicatorattentionicon(drawable attentionicon) {
    mstepsviewindicator.setattentionicon(attentionicon);
    return this;
  }
  public horizontalstepview setstepsviewindicatorlastcompleteicon(drawable lastcompleteicon) {
    mstepsviewindicator.setlastcompleteicon(lastcompleteicon);
    return this;
  }
  public horizontalstepview setstepsviewindicatorlastuncompleteicon(drawable lastuncompleteicon) {
    mstepsviewindicator.setlastuncompleteicon(lastuncompleteicon);
    return this;
  }
  /**
   * set textsize
   * @param textsize
   * @return
   */
  public horizontalstepview settextsize(int textsize) {
    if(textsize > 0) {
      mtextsize = textsize;
    }
    return this;
  }
  @override
  public void ondrawindicator() {
    if(mtextcontainer != null) {
      mtextcontainer.removeallviews();
      list<float> complectedxposition = mstepsviewindicator.getcirclecenterpointpositionlist();
      if(mstepbeanlist != null && complectedxposition != null && complectedxposition.size() > 0) {
        for(int i = 0; i < mstepbeanlist.size(); i++) {
          mtextview = new textview(getcontext());
          mtextview.settextsize(typedvalue.complex_unit_sp, mtextsize);
          mtextview.settext(mstepbeanlist.get(i).getname());
          int spec = measurespec.makemeasurespec(0, measurespec.unspecified);
          mtextview.measure(spec, spec);
          // getmeasuredwidth
          int measuredwidth = mtextview.getmeasuredwidth();
          mtextview.setx(complectedxposition.get(i) - measuredwidth / 2);
          mtextview.setlayoutparams(new viewgroup.layoutparams(viewgroup.layoutparams.wrap_content, viewgroup.layoutparams.wrap_content));
          if(i <= mcomplectingposition) {
            mtextview.settypeface(null);
            mtextview.settextcolor(mcomplectedtextcolor);
          } else{
            mtextview.settextcolor(muncomplectedtextcolor);
          }
          mtextcontainer.addview(mtextview);
        }
      }
    }
  }
}

step4:如何使用?

在布局文件xml中:

<cn.comnav.utrain.ui.widget.horizontalstepview
          android:id="@+id/hsv_step_view"
          android:layout_width="match_parent"
          android:layout_height="80dp"
          android:layout_below="@+id/ll_role"
          android:layout_marginbottom="40dp"
          />

在activity中的使用,部分代码截取:

private list<stepbean> stepsbeanlist;
         private horizontalstepview mhorizontalstepview;
         mhorizontalstepview=(horizontalstepview)findviewbyid(r.id.hsv_step_view);
         stepsbeanlist = new arraylist<>();
            stepbean stepbean0=null;
            stepbean stepbean1=null;
            stepbean stepbean2=null;
            stepbean stepbean3=null;
            switch (stepindex){
              case 1:
                stepbean0 = new stepbean("手机绑定",1);
                stepbean1 = new stepbean("实名认证",0);
                stepbean2 = new stepbean("学时充值",-1);
                stepbean3 = new stepbean("开始用车",3);
                break;
              case 2:
                stepbean0 = new stepbean("手机绑定",1);
                stepbean1 = new stepbean("实名认证",1);
                stepbean2 = new stepbean("学时充值",0);
                stepbean3 = new stepbean("开始用车",3);
                break;
              case 3:
                stepbean0 = new stepbean("手机绑定",1);
                stepbean1 = new stepbean("实名认证",1);
                stepbean2 = new stepbean("学时充值",1);
                stepbean3 = new stepbean("开始用车",2);
                break;
            }
            stepsbeanlist.add(stepbean0);
            stepsbeanlist.add(stepbean1);
            stepsbeanlist.add(stepbean2);
            stepsbeanlist.add(stepbean3);
          mhorizontalstepview.setstepviewtexts(stepsbeanlist);

以上所述是小编给大家介绍的android 仿摩拜单车共享单车进度条实现stepview效果,希望对大家有所帮助