jjzjj

属性动画的核心方法:ValueAnimator.ofInt(int... values)

听着music睡 2023-03-28 原文

该方法的实现目的:以整形初始值平稳过渡到整形结束值。

比如 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

 

ValueAnimatorvaluesspancolorstyle移动端开发

有关属性动画的核心方法:ValueAnimator.ofInt(int... values)的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  6. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  7. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  8. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  9. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  10. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

随机推荐