屬性動畫的核心方法:ValueAnimator.ofInt(int... values)
阿新 • • 發佈:2021-10-25
該方法的實現目的:以整形初始值平穩過渡到整形結束值。
比如 ValueAnimator.ofInt(0,100) , 實現的即數值從0平穩的變化到100
比如實現如下一個效果:
改變控制元件的樣式,圓形和圓角長方形切換
實現思路很簡單,即高度不變,改變控制元件的寬度(圓形時:寬高相等,長方形時:寬度為螢幕寬度-兩邊邊距),順便設定一個背景值,動畫執行過程隨便設個值(例子250毫秒)
現在看具體實現:
1、首先佈局檔案,設定兩個按鈕和一個效果控制元件 , 這裡設定執行效果控制元件的高度固定為50dp,當然可以自行擴充套件
1 <?xml version="1.0" encoding="utf-8"?> 2xml佈局檔案<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" 8android: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>
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
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。