Android自定義進(jìn)度條效果
最近項目中需要在一個功能模塊中使用進(jìn)度條,效果圖如下:


上面圖片從左到右分別是效果一,效果二,效果三
需求: 以下四點需要實現(xiàn)
1: 當(dāng)沒有沒完成進(jìn)度的時候,顯示效果一
2:當(dāng)進(jìn)度完成了一部分,顯示圖二
3:當(dāng)進(jìn)度全部完成之后,顯示效果三
4:當(dāng)進(jìn)度1到進(jìn)度2需要動畫,進(jìn)度2到進(jìn)度3需要動畫; 同樣進(jìn)度3到進(jìn)度2或者進(jìn)度1也需要動畫。
剛開始拿到這個東西的時候,考慮了老長時間,覺得還是有技巧的,先說一下思路吧
首先我們,寫一個一模一樣的底部布局,如下圖1:

圖一也就是效果一的全部顯示,

圖三不是跟圖一一模一樣嗎? 是的,但是字體的顏色不一樣的,圖三的顏色的白色的,然后把圖三放進(jìn)圖二中,得到圖四, 因為圖二是父布局,圖三是子布局,圖三放在圖二中,只會顯示部分的視圖。 此時在把圖四和圖一疊加!
注意:圖一在圖四的下面。
如下圖所示,得到圖五:

上圖是大致的思路,接下來看下我們用Java代碼應(yīng)該怎樣思考:
- XML中首先最外層是RelativeLayout,
- 然后父布局里面有兩個,分別是圖一和圖四的布局,圖一的布局可以使RelativeLayout,圖四的布局我們需要自定義GroupView,需要繼承自LinearLayout,至于為什么不是繼承自RelativeLayout,實驗是不行的,這是一個疑惑點。
- 在XML中,靜態(tài)在自定義GroupView中添加跟圖一一樣的布局,但是需要注意的是,顏色不能一致!
- 在自定義的布局中,我們需要動態(tài)更改自定義ViewGroup的寬度,也就是動態(tài)更改圖二的寬度。
接下來看下具體的代碼實現(xiàn):
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="體制數(shù)據(jù)完善度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="體制數(shù)據(jù)完善度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; //每個進(jìn)度的寬度
private int progressIntervalWidth; //相應(yīng)進(jìn)度占的寬度
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 本次進(jìn)度
* @return
*/
public MineProgressLinearLayout setNowProgress(int nowProgress) {
this.nowProgress = nowProgress;
return MineProgressLinearLayout.this;
}
/**
*
* @param totalProgress 總進(jìn)度
* @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) { //現(xiàn)有進(jìn)度不能大于總進(jìn)度
nowProgress = totalProgress;
}
if(totalProgress < preProgress) { //上一個進(jìn)度不能大于總進(jìn)度
preProgress = totalProgress;
}
spaceInterval = widthRelative / totalProgress;
progressIntervalWidth = spaceInterval * nowProgress;
//設(shè)置父View的寬度
parentLayoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
//如果傳入的進(jìn)度為0 或者 之前的進(jìn)度等于progressCount的進(jìn)度 則不用更改寬度
if (nowProgress == 0 || preProgress == nowProgress) {
parentLayoutParams.width = progressIntervalWidth;
setLayoutParams(parentLayoutParams);
return;
}
//設(shè)置子View的寬度
RelativeLayout childAt = (RelativeLayout) getChildAt(0);
LinearLayout.LayoutParams childAtLp = (LayoutParams) childAt.getLayoutParams();
childAtLp.width = widthRelative;
childAt.setLayoutParams(childAtLp);
//設(shè)置父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時,關(guān)閉動畫
public void cancelAnimation() {
if(valueAnimator != null) {
valueAnimator.cancel();
valueAnimator = null;
}
}
}
4: 調(diào)用:
mineProgressLinearlayout.setLayoutWidth(widthLayout) .setNowProgress(nowMineProgress) .setTotalProgress(totalMineProgress).build();
實際上我覺得,代碼不難,重要的是原理是怎么實現(xiàn)的,因為知道不同的原理會寫出不同的代碼。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android 七種進(jìn)度條的樣式
- Android中實現(xiàn)Webview頂部帶進(jìn)度條的方法
- android自定義進(jìn)度條漸變色View的實例代碼
- Android文件下載進(jìn)度條的實現(xiàn)代碼
- android ListView和ProgressBar(進(jìn)度條控件)的使用方法
- Android中自定義進(jìn)度條詳解
- 實例詳解Android自定義ProgressDialog進(jìn)度條對話框的實現(xiàn)
- Android編程之ProgressBar圓形進(jìn)度條顏色設(shè)置方法
- Android三種方式實現(xiàn)ProgressBar自定義圓形進(jìn)度條
- Android ProgressBar進(jìn)度條使用詳解
相關(guān)文章
淺析Android手機(jī)衛(wèi)士之手機(jī)實現(xiàn)短信指令獲取位置
這篇文章主要介紹了淺析Android手機(jī)衛(wèi)士之手機(jī)實現(xiàn)短信指令獲取位置的相關(guān)資料,需要的朋友可以參考下2016-04-04
Android Studio 全屏沉浸式透明狀態(tài)欄效果的實現(xiàn)
這篇文章主要介紹了Android Studio 全屏沉浸式透明狀態(tài)欄效果,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
Android Studio實現(xiàn)簡單的QQ登錄界面的示例代碼
這篇文章主要介紹了Android Studio實現(xiàn)簡單的QQ登錄界面的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Android Intent與IntentFilter案例詳解
這篇文章主要介紹了Android Intent與IntentFilter案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
Android開發(fā)之日歷CalendarView用法示例
這篇文章主要介紹了Android開發(fā)之日歷CalendarView用法,簡單分析了日歷CalendarView組件的功能、屬性設(shè)置方法、界面布局、事件監(jiān)聽等相關(guān)操作技巧,需要的朋友可以參考下2019-03-03
Android教你如何發(fā)現(xiàn)APP卡頓的實現(xiàn)
這篇文章主要介紹了Android教你如何發(fā)現(xiàn)APP卡頓的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

