1. 程式人生 > 其它 >屬性動畫的核心方法:ValueAnimator.ofInt(int... values)

屬性動畫的核心方法:ValueAnimator.ofInt(int... values)

該方法的實現目的:以整形初始值平穩過渡到整形結束值。

比如 ValueAnimator.ofInt(0,100) , 實現的即數值從0平穩的變化到100

比如實現如下一個效果:

改變控制元件的樣式,圓形和圓角長方形切換

實現思路很簡單,即高度不變,改變控制元件的寬度(圓形時:寬高相等,長方形時:寬度為螢幕寬度-兩邊邊距),順便設定一個背景值,動畫執行過程隨便設個值(例子250毫秒)

現在看具體實現:

1、首先佈局檔案,設定兩個按鈕和一個效果控制元件 , 這裡設定執行效果控制元件的高度固定為50dp,當然可以自行擴充套件

 1 <?xml version="1.0" encoding="utf-8"?>
 2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:orientation="vertical" 8
android:gravity="center" 9 tools:context=".MainActivity"> 10 11 <TextView 12 android:id="@+id/tvToCir" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:gravity="center" 16 android:text="長方形變圓形" 17 android:padding="10dp" 18
></TextView> 19 20 21 <TextView 22 android:id="@+id/tvToRect" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:gravity="center" 26 android:text="圓形變長方形" 27 android:padding="10dp" 28 android:layout_marginTop="20dp" 29 ></TextView> 30 31 32 <TextView 33 android:id="@+id/tvAdd" 34 android:layout_width="match_parent" 35 android:layout_height="50dp" 36 android:text="+" 37 android:gravity="center" 38 android:textColor="#fff" 39 android:background="@drawable/shape_main_add_rect" 40 app:layout_constraintRight_toRightOf="parent" 41 android:layout_marginRight="30dp" 42 android:layout_marginLeft="30dp" 43 android:layout_marginTop="30dp" 44 app:layout_constraintBottom_toBottomOf="parent" 45 android:layout_marginBottom="30dp" 46 /> 47 48 </LinearLayout>
xml佈局檔案

2、分別寫下長方形和圓形狀態時對應的背景檔案,即drawable型別的shape屬性

(1)圓形,圓角為25dp(因為寬度為50dp,設定一半數值即為圓形效果), 背景綠色,再加一個白色的邊,為了效果好看些

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 3     <!--第一層陰影-->
 4     <item>
 5         <shape android:shape="rectangle">
 6             <solid android:color="#0F000000" />
 7             <corners android:radius="25dp" />
 8         </shape>
 9     </item>
10     <item
11         android:bottom="2dp"
12         android:left="2dp"
13         android:right="2dp"
14         android:top="2dp">
15         <shape android:shape="rectangle">
16             <solid android:color="#fff" />
17             <corners android:radius="25dp" />
18         </shape>
19     </item>
20     <!--第二層前景-->
21     <item
22         android:bottom="5dp"
23         android:left="5dp"
24         android:right="5dp"
25         android:top="5dp">
26         <shape android:shape="rectangle">
27             <solid android:color="#29C66A"/>
28             <corners android:radius="25dp" />
29         </shape>
30     </item>
31 
32 </layer-list>
shape_main_add_cir.xml

(2)長方形,同上,不過圓角設定可以設定小一點,這個讀者可以仿著圓角自己寫一個,完整程式碼請到最後檢視

3、動畫的實現方法,以長方形到圓形為例,只需依賴ValueAnimator.ofInt()方法設定數值從25dp到螢幕寬度-兩邊邊距即可

 1 // 長方形變圓形
 2     public void rectToCir(){
 3         // 異常,如果動畫物件為null 或者 動畫在執行中
 4         if (valAnimator!=null && valAnimator.isRunning()){
 5             return;
 6         }
 7         // 長方形寬度為螢幕寬度-去兩邊各30dp, 圓形寬度為50dp, 因為設定的空間高度為50dp,圓角為25dp,即實現了圓形圖示
 8         // ofInt(int a, int b)表示 動畫取值從a到b
 9         valAnimator = ValueAnimator.ofInt(screenWidth-2*dpToPx(30), dpToPx(50));
10         valAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
11             @Override
12             public void onAnimationUpdate(ValueAnimator animation) {
13                 // 定義動畫的值,即ofInt方法設定的取值範圍,值變化時即執行該回調
14                 int h = (int) animation.getAnimatedValue();
15                 // 結果處理,若值為寬度-2*50dp,說明為長方形,則設定文案
16                 if (h==screenWidth-2*dpToPx(30)){
17                     tvAdd.setText("");
18                 }else if (h==dpToPx(50)){
19                     // 說明變圓形了,設定文案 , 同時設定背景
20                     tvAdd.setText("+");
21                     tvAdd.setTextSize(14);
22                     tvAdd.setBackgroundResource(R.drawable.shape_main_add_cir);
23                 }
24                 LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) tvAdd.getLayoutParams(); //取控制元件textView當前的佈局引數
25                 linearParams.width = h;// 控制元件的高強制設成20
26                 tvAdd.setLayoutParams(linearParams);
27 
28             }
29         });
30         // 動畫執行過程為250毫秒
31         valAnimator.setDuration(250);
32         // 開始執行動畫
33         valAnimator.start();
34     }

Activity完整程式碼如下:

  1 package com.mxqx.xqxtest;
  2 
  3 import androidx.appcompat.app.AppCompatActivity;
  4 
  5 import android.animation.ValueAnimator;
  6 import android.content.res.Resources;
  7 import android.os.Bundle;
  8 import android.view.View;
  9 import android.view.WindowManager;
 10 import android.widget.LinearLayout;
 11 import android.widget.TextView;
 12 /**
 13  * @author : https://www.cnblogs.com/xqxacm/ xqx
 14  * @create_day : 2021/10/2
 15  * @description :
 16  */
 17 public class MainActivity extends AppCompatActivity {
 18 
 19     TextView tvToCir;   // 長方形變圓形按鈕
 20     TextView tvToRect;  // 圓形變長方形按鈕
 21     TextView tvAdd;     // 新增按鈕
 22     int screenWidth = 0;  // 螢幕寬度
 23     @Override
 24     protected void onCreate(Bundle savedInstanceState) {
 25         super.onCreate(savedInstanceState);
 26         setContentView(R.layout.activity_main);
 27         initView();
 28     }
 29 
 30     private void initView() {
 31         tvToCir = findViewById(R.id.tvToCir);
 32         tvToRect = findViewById(R.id.tvToRect);
 33         tvAdd = findViewById(R.id.tvAdd);
 34         // 獲取螢幕寬度
 35         WindowManager wm1 = this.getWindowManager();
 36         screenWidth = wm1.getDefaultDisplay().getWidth();
 37 
 38         // 點選事件
 39         tvToCir.setOnClickListener(new View.OnClickListener() {
 40             @Override
 41             public void onClick(View view) {
 42                 // 長方形變圓形
 43                 rectToCir();
 44             }
 45         });
 46         tvToRect.setOnClickListener(new View.OnClickListener() {
 47             @Override
 48             public void onClick(View view) {
 49                 // 圓形變長方形
 50                 cirToTri();
 51             }
 52         });
 53     }
 54 
 55     ValueAnimator valAnimator ;
 56     // 長方形變圓形
 57     public void rectToCir(){
 58         // 異常,如果動畫物件為null 或者 動畫在執行中
 59         if (valAnimator!=null && valAnimator.isRunning()){
 60             return;
 61         }
 62         // 長方形寬度為螢幕寬度-去兩邊各30dp, 圓形寬度為50dp, 因為設定的空間高度為50dp,圓角為25dp,即實現了圓形圖示
 63         // ofInt(int a, int b)表示 動畫取值從a到b
 64         valAnimator = ValueAnimator.ofInt(screenWidth-2*dpToPx(30), dpToPx(50));
 65         valAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 66             @Override
 67             public void onAnimationUpdate(ValueAnimator animation) {
 68                 // 定義動畫的值,即ofInt方法設定的取值範圍,值變化時即執行該回調
 69                 int h = (int) animation.getAnimatedValue();
 70                 // 結果處理,若值為寬度-2*50dp,說明為長方形,則設定文案
 71                 if (h==screenWidth-2*dpToPx(30)){
 72                     tvAdd.setText("");
 73                 }else if (h==dpToPx(50)){
 74                     // 說明變圓形了,設定文案 , 同時設定背景
 75                     tvAdd.setText("+");
 76                     tvAdd.setTextSize(14);
 77                     tvAdd.setBackgroundResource(R.drawable.shape_main_add_cir);
 78                 }
 79                 LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) tvAdd.getLayoutParams(); //取控制元件textView當前的佈局引數
 80                 linearParams.width = h;// 控制元件的高強制設成20
 81                 tvAdd.setLayoutParams(linearParams);
 82 
 83             }
 84         });
 85         // 動畫執行過程為250毫秒
 86         valAnimator.setDuration(250);
 87         // 開始執行動畫
 88         valAnimator.start();
 89     }
 90     // 圓形變長方形
 91     public void cirToTri(){
 92         if (valAnimator!=null && valAnimator.isRunning()){
 93             return;
 94         }
 95         valAnimator = ValueAnimator.ofInt(dpToPx(50), screenWidth-2*dpToPx(30));
 96         valAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 97             @Override
 98             public void onAnimationUpdate(ValueAnimator animation) {
 99                 int h = (int) animation.getAnimatedValue();
100                 if (h==screenWidth-2*dpToPx(30)){
101                     tvAdd.setText("新增");
102                     tvAdd.setBackgroundResource(R.drawable.shape_main_add_rect);
103                 }else if (h==dpToPx(50)){
104                     tvAdd.setText("");
105                 }
106                 LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) tvAdd.getLayoutParams(); //取控制元件textView當前的佈局引數
107                 linearParams.width = h;// 控制元件的高強制設成20
108                 tvAdd.setLayoutParams(linearParams);
109 
110             }
111         });
112         valAnimator.setDuration(250);
113         valAnimator.start();
114     }
115 
116     /**
117      * 把以 dp 為單位的值,轉化為以 px 為單位的值
118      *
119      * @param dpValue 以 dp 為單位的值
120      * @return px value
121      */
122     public static int dpToPx(int dpValue) {
123         return (int) (dpValue * DENSITY + 0.5f);
124     }
125     /**
126      * 螢幕密度,系統原始碼註釋不推薦使用
127      */
128     public static final float DENSITY = Resources.getSystem()
129             .getDisplayMetrics().density;
130 }
MainActivity.java

作者:聽著music睡

出處:http://www.cnblogs.com/xqxacm/

Android交流群:38197636

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。