当前位置: 移动技术网 > 移动技术>移动开发>Android > Android 仿摩拜单车共享单车进度条实现StepView效果

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

先看效果图:

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效果,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网