成都网站建设设计

将想法与焦点和您一起共享

如何在Android中自定义一个进度条效果

这篇文章将为大家详细讲解有关如何在Android中自定义一个进度条效果,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

成都创新互联公司-专业网站定制、快速模板网站建设、高性价比奇台网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式奇台网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖奇台地区。费用合理售后完善,10年实体公司更值得信赖。

需求: 以下四点需要实现 

1: 当没有没完成进度的时候,显示效果一
2:当进度完成了一部分,显示图二
3:当进度全部完成之后,显示效果三
4:当进度1到进度2需要动画,进度2到进度3需要动画; 同样进度3到进度2或者进度1也需要动画。

刚开始拿到这个东西的时候,考虑了老长时间,觉得还是有技巧的,先说一下思路吧

首先我们,写一个一模一样的底部布局,如下图1:

如何在Android中自定义一个进度条效果

图一也就是效果一的全部显示,

如何在Android中自定义一个进度条效果
如何在Android中自定义一个进度条效果
如何在Android中自定义一个进度条效果

图三不是跟图一一模一样吗? 是的,但是字体的颜色不一样的,图三的颜色的白色的,然后把图三放进图二中,得到图四, 因为图二是父布局,图三是子布局,图三放在图二中,只会显示部分的视图。 此时在把图四和图一叠加!

注意:图一在图四的下面。

如下图所示,得到图五:

如何在Android中自定义一个进度条效果

上图是大致的思路,接下来看下我们用Java代码应该怎样思考:

  • XML中首先最外层是RelativeLayout,

  • 然后父布局里面有两个,分别是图一和图四的布局,图一的布局可以使RelativeLayout,图四的布局我们需要自定义GroupView,需要继承自LinearLayout,至于为什么不是继承自RelativeLayout,实验是不行的,这是一个疑惑点。

  • 在XML中,静态在自定义GroupView中添加跟图一一样的布局,但是需要注意的是,颜色不能一致

  • 在自定义的布局中,我们需要动态更改自定义ViewGroup的宽度,也就是动态更改图二的宽度。

接下来看下具体的代码实现:

1:drawable文件的shape文件:

drawable_rectangle_raduis_50_color_0a3f6d_to_fc6f54.xml 图二的shape



  
  

  

drawable_rectangle_raduis_50_color_f0eff4.xml 图一的shape



  

  

2:xml文件:


  
    

    
  

  
    
      

      
    
  

3: MineProgressLinearLayout.java:

package com.bluetown.health.mine;

import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;

import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.bluetown.health.R;

/**
 * Created by ${liumengqiang} on 2018/3/20.
 */

public class MineProgressLinearLayout extends LinearLayout {

  private int widthRelative; //控件的宽度

  private int spaceInterval; //每个进度的宽度

  private int progressIntervalWidth; //相应进度占的宽度

  private ValueAnimator valueAnimator; //动画

  private RelativeLayout.LayoutParams parentLayoutParams; //该ViewGroup的LP

  private int preProgress;

  private int nowProgress;

  private int totalProgress;

  public MineProgressLinearLayout(Context context) {
    super(context);
  }

  public MineProgressLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public MineProgressLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }

  /**
   * @param width 最大宽度
   * @return
   */
  public MineProgressLinearLayout setLayoutWidth(int width) {
    widthRelative = width;
    return MineProgressLinearLayout.this;
  }

  /**
   *
   * @param nowProgress 本次进度
   * @return
   */
  public MineProgressLinearLayout setNowProgress(int nowProgress) {
    this.nowProgress = nowProgress;
    return MineProgressLinearLayout.this;
  }

  /**
   *
   * @param totalProgress 总进度
   * @return
   */
  public MineProgressLinearLayout setTotalProgress(int totalProgress) {
    this.totalProgress = totalProgress;
    return MineProgressLinearLayout.this;
  }

  public void build() {
    reSetWidthData();
  }

  private void reSetWidthData() {

    if(totalProgress == 0) { //
      setVisibility(View.GONE);
      return;
    }

    if(totalProgress < nowProgress) { //现有进度不能大于总进度
      nowProgress = totalProgress;
    }

    if(totalProgress < preProgress) { //上一个进度不能大于总进度
      preProgress = totalProgress;
    }

    spaceInterval = widthRelative / totalProgress;
    progressIntervalWidth = spaceInterval * nowProgress;

    //设置父View的宽度
    parentLayoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
    //如果传入的进度为0 或者 之前的进度等于progressCount的进度 则不用更改宽度
    if (nowProgress == 0 || preProgress == nowProgress) {
      parentLayoutParams.width = progressIntervalWidth;
      setLayoutParams(parentLayoutParams);
      return;
    }

    //设置子View的宽度
    RelativeLayout childAt = (RelativeLayout) getChildAt(0);
    LinearLayout.LayoutParams childAtLp = (LayoutParams) childAt.getLayoutParams();
    childAtLp.width = widthRelative;
    childAt.setLayoutParams(childAtLp);

    //设置父View的背景色
    setBackgroundResource(R.drawable.drawable_rectangle_raduis_50_color_0a3f6d_to_fc6f54);

    startAnimation();
  }

  //开启动画
  private void startAnimation() {
    valueAnimator = ValueAnimator.ofInt(preProgress * spaceInterval, nowProgress * spaceInterval);
    valueAnimator.setDuration(1000);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        parentLayoutParams.width = (int) animation.getAnimatedValue();
        setLayoutParams(parentLayoutParams);

        preProgress = nowProgress;
      }
    });
    valueAnimator.start();
  }

  // 退出Activity时,关闭动画
  public void cancelAnimation() {
    if(valueAnimator != null) {
      valueAnimator.cancel();
      valueAnimator = null;
    }
  }
}

4: 调用:

mineProgressLinearlayout.setLayoutWidth(widthLayout)
   .setNowProgress(nowMineProgress)
   .setTotalProgress(totalMineProgress).build();

关于如何在Android中自定义一个进度条效果就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


分享标题:如何在Android中自定义一个进度条效果
网站路径:http://chengdu.cdxwcx.cn/article/jspoco.html