首页 > 系统 > Android > 正文

Android自定义进度条效果

2019-10-21 21:42:42
字体:
来源:转载
供稿:网友

最近项目中需要在一个功能模块中使用进度条,效果图如下:

Android,进度条

Android,进度条

上面图片从左到右分别是效果一,效果二,效果三 

需求: 以下四点需要实现 

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

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"  android:shape="rectangle">  <!-- 渐变色 -->  <gradient    android:endColor="#FC6F54"    android:startColor="#0A3F6D"    android:type="linear"/>  <corners android:radius="50dp" /></shape>

drawable_rectangle_raduis_50_color_f0eff4.xml 图一的shape

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"  android:shape="rectangle">  <solid android:color="@color/color_f0eff4"/>  <corners android:radius="50dp" /></shape>

2:xml文件:

<RelativeLayout  android:id="@+id/mine_progress_bottom_relayout"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_marginStart="@dimen/margin_20"  android:layout_marginEnd="@dimen/margin_20">  <RelativeLayout    android:layout_width="match_parent"    android:layout_height="50dp"    android:paddingEnd="@dimen/margin_16"    android:background="@drawable/drawable_rectangle_raduis_50_color_f0eff4">    <TextView      android:id="@+id/mine_progress_bottom_text"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:layout_centerInParent="true"      android:text="体制数据完善度2/5"      android:textSize="15dp"      android:textColor="@color/color_0A3F6D"/>    <ImageView      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:src="@mipmap/ic_mine_progress"      android:layout_alignParentEnd="true"      android:layout_centerVertical="true"/>  </RelativeLayout>  <com.bluetown.health.mine.MineProgressLinearLayout    android:id="@+id/mine_progress_relayout"    android:layout_width="match_parent"    android:layout_height="50dp"    android:visibility="gone">    <RelativeLayout      android:layout_width="wrap_content"      android:layout_height="50dp"      android:paddingEnd="@dimen/margin_16">      <TextView        android:id="@+id/mine_progress_top_text"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:text="体制数据完善度2/5"        android:textSize="15dp"        android:textColor="@color/color_ffffff"/>      <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@mipmap/ic_mine_white"        android:layout_alignParentEnd="true"        android:layout_centerVertical="true"/>    </RelativeLayout>  </com.bluetown.health.mine.MineProgressLinearLayout></RelativeLayout>

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();

实际上我觉得,代码不难,重要的是原理是怎么实现的,因为知道不同的原理会写出不同的代码。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表