最近項目中需要在一個功能模塊中使用進度條,效果圖如下:
上面圖片從左到右分別是效果一,效果二,效果三
需求: 以下四點需要實現
1: 當沒有沒完成進度的時候,顯示效果一
2:當進度完成了一部分,顯示圖二
3:當進度全部完成之后,顯示效果三
4:當進度1到進度2需要動畫,進度2到進度3需要動畫; 同樣進度3到進度2或者進度1也需要動畫。
剛開始拿到這個東西的時候,考慮了老長時間,覺得還是有技巧的,先說一下思路吧
首先我們,寫一個一模一樣的底部布局,如下圖1:
圖一也就是效果一的全部顯示,
圖三不是跟圖一一模一樣嗎? 是的,但是字體的顏色不一樣的,圖三的顏色的白色的,然后把圖三放進圖二中,得到圖四, 因為圖二是父布局,圖三是子布局,圖三放在圖二中,只會顯示部分的視圖。 此時在把圖四和圖一疊加!
注意:圖一在圖四的下面。
如下圖所示,得到圖五:
上圖是大致的思路,接下來看下我們用Java代碼應該怎樣思考:
接下來看下具體的代碼實現:
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武林網。
新聞熱點
疑難解答