zoukankan      html  css  js  c++  java
  • 属性动画的核心方法: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

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Ping 笔记
    android之RadioGroup
    Android之activity中新建控件
    案例:TableLayout表格布局——迷你计算器
    android中5大布局
    Android体系结构及activity生命周期
    Android之ADB指令
    Android之activity初讲
    简单介绍Android应用特色及详解四大组件
    开发Android应用怎么更改LOGO图标
  • 原文地址:https://www.cnblogs.com/xqxacm/p/15457512.html
Copyright © 2011-2022 走看看