属性动画的核心方法: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

 

posted @ 2021-10-25 11:01  听着music睡  阅读(663)  评论(0编辑  收藏  举报