【移动开发】Android波纹动画效果实现

简介:

今天我实现一个wifi当中搜索时的动画效果,通常我们会使用多张图片进行Frame动画播放,这里我使用了Tween动画,仅对一张图片进行操作,实现了wifi扫描动画效果,有兴趣的可以看看!

效果图:

180752274.png


这里我们采用了自定义布局的方式 activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
< RelativeLayout  xmlns:android = "http://schemas.android.com/apk/res/android"
     xmlns:tools = "http://schemas.android.com/tools"
     android:layout_width = "match_parent"
     android:layout_height = "match_parent"
     >
     < com.zhf.android_ripple.AnimationFrameLayout
         android:id = "@+id/search_animation_wf_main"
         android:layout_width = "fill_parent"
         android:layout_height = "fill_parent"  >
     </ com.zhf.android_ripple.AnimationFrameLayout >
     < Button
         android:id = "@+id/button1"
         android:layout_width = "wrap_content"
         android:layout_height = "wrap_content"
         android:layout_alignParentRight = "true"
         android:text = "开启波纹动画"  />
</ RelativeLayout >


AnimationFrameLayout类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package  com.zhf.android_ripple;
import  java.lang.ref.SoftReference;
import  android.content.Context;
import  android.graphics.Bitmap;
import  android.graphics.BitmapFactory;
import  android.util.AttributeSet;
import  android.util.Log;
import  android.view.LayoutInflater;
import  android.view.View;
import  android.view.animation.AccelerateDecelerateInterpolator;
import  android.view.animation.AlphaAnimation;
import  android.view.animation.Animation;
import  android.view.animation.Animation.AnimationListener;
import  android.view.animation.AnimationSet;
import  android.view.animation.ScaleAnimation;
import  android.widget.FrameLayout;
import  android.widget.ImageView;
public  class  AnimationFrameLayout  extends  FrameLayout {
     private  SoftReference<Bitmap> m_bitmapRipple; //波纹图片 (软引用)
     private  ImageView[] m_imageVRadars;  //ImageView数组
                                                                                                                              
     public  AnimationFrameLayout(Context context) {
         super (context);
         init();
     }
     public  AnimationFrameLayout(Context context, AttributeSet attrs,
             int  defStyle) {
         super (context, attrs, defStyle);
         init();
     }
     public  AnimationFrameLayout(Context context, AttributeSet attrs) {
         super (context, attrs);
         init();
     }
     /**初始化**/
     private  void  init() {
         loadRadarBitmap();
         m_imageVRadars =  new  ImageView[ 3 ];
         View v = LayoutInflater.from(getContext()).inflate(R.layout.wt_search_device_anima,  this );
         m_imageVRadars[ 0 ] = (ImageView) v.findViewById(R.id.radar_ray_1);
         m_imageVRadars[ 1 ] = (ImageView) v.findViewById(R.id.radar_ray_2);
         m_imageVRadars[ 2 ] = (ImageView) v.findViewById(R.id.radar_ray_3);
     }
     /**加载图片**/
     private  void  loadRadarBitmap() {
         try  {
             //获取波纹图片
             m_bitmapRipple =  new  SoftReference<Bitmap>(BitmapFactory.decodeStream(getContext().getResources()
                             .openRawResource(R.drawable.wifi_body_ripple)));
         catch  (Exception localException) {
             Log.e( "WTSearchAnimationFrameLayout" ,
                     Log.getStackTraceString(localException));
         catch  (OutOfMemoryError localOutOfMemoryError) {
             Log.e( "WTSearchAnimationFrameLayout" ,
                     Log.getStackTraceString(localOutOfMemoryError));
             System.gc();   //回收
         }
     }
                                                                                                                              
     /**重置,停止动画**/
     public  void  stopAnimation() {
         for  ( int   i=  0 ;  i< m_imageVRadars.length; ++i) {
             if (m_bitmapRipple !=  null ){
                 Bitmap localBitmap = m_bitmapRipple.get();  //软引用获取对象
                 if (localBitmap !=  null  && !localBitmap.isRecycled()) {
                     //回收图片资源
                     localBitmap.recycle();
                 }
                 m_bitmapRipple =  null ;
                 ImageView localImageView = m_imageVRadars[i];
                 localImageView.setImageBitmap( null );  //设置ImageView为空
                 localImageView.setVisibility(View.GONE);
                 localImageView.clearAnimation();  //取消动画
             }
         }
     }
                                                                                                                              
     /**开始动画**/
     public  void  startAnimation() {
         if (m_bitmapRipple ==  null ) {
             loadRadarBitmap();
         }
         for  ( int  i =  0 ; i < m_imageVRadars.length; i++) {
             ImageView localImageView;
             long  ltime;
             while ( true ) {
                 localImageView = m_imageVRadars[i];
                 localImageView.setImageBitmap(m_bitmapRipple.get());   //获取图片
                 localImageView.setVisibility(View.VISIBLE);
                 //放大
                 ltime= 333L * i;
                 if (localImageView.getAnimation() ==  null ) {
                     break ;
                 }
                 localImageView.getAnimation().start();
             }
                                                                                                                                      
             ScaleAnimation localScaleAnimation =  new  ScaleAnimation( 1 .0f,  14 .0f, 1 .0f, 14 .0f, 1 , 0 .5f, 1 , 0 .5f);
             localScaleAnimation.setRepeatCount(- 1 );  //动画重复
             AlphaAnimation localAlphaAnimation =  new  AlphaAnimation( 1 .0f,  0 .2f);
             AnimationSet localAnimationSet =  new  AnimationSet( true );   //true:使用相同的加速器
                                                                                                                                      
             localAnimationSet.addAnimation(localScaleAnimation);
             localAnimationSet.addAnimation(localAlphaAnimation);   //将两种动画效果添加进去
             //设置相关属性
             localAnimationSet.setDuration(1000L);   //持续时间
             localAnimationSet.setFillEnabled( true );
             localAnimationSet.setFillBefore( true );   //控件保持在动画开始之前
             localAnimationSet.setStartOffset(ltime);    //动画效果推迟ltime秒钟后启动
             localAnimationSet.setInterpolator( new  AccelerateDecelerateInterpolator());
             localAnimationSet.setAnimationListener( new  MySearchAnimationHandler( this ,localImageView));  //绑定监听器
             //将动画集合设置进去
             localImageView.setAnimation(localAnimationSet);
             localImageView.startAnimation(localAnimationSet); //开启动画
         }
     }
     /**动画监听类**/
     public  class  MySearchAnimationHandler  implements  AnimationListener{
         private  ImageView m_imageVRadar;
                                                                                                                                  
         public  MySearchAnimationHandler(AnimationFrameLayout paramImageView,ImageView m_imageVRadar) {
             super ();
             this .m_imageVRadar = m_imageVRadar;
         }
         @Override
         public  void  onAnimationStart(Animation animation) {
             // TODO Auto-generated method stub
         }
         @Override
         public  void  onAnimationEnd(Animation animation) {
             this .m_imageVRadar.setVisibility(View.GONE);
         }
         @Override
         public  void  onAnimationRepeat(Animation animation) {
             animation.setStartOffset(0L);
         }
     }
}

重要说明:

1.该类中我们对图片的操作使用软引用,目的是防止OOM.

2.至于动画,使用ImageView[]来依次加载图片,通过更改对每个ImageView实现缩放和透明动画


动画布局  wt_search_device_anima.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<? xml  version = "1.0"  encoding = "utf-8" ?>
< RelativeLayout  xmlns:android = "http://schemas.android.com/apk/res/android"
     android:layout_width = "fill_parent"
     android:layout_height = "fill_parent"  >
     < ImageView
         android:id = "@+id/radar_ray_1"
         android:layout_width = "70.0dip"
         android:layout_height = "70.0dip"
         android:layout_alignParentRight = "true"
         android:layout_alignParentTop = "true"
         android:layout_marginLeft = "10.0dip"  />
     < ImageView
         android:id = "@+id/radar_ray_2"
         android:layout_width = "70.0dip"
         android:layout_height = "70.0dip"
         android:layout_alignParentRight = "true"
         android:layout_alignParentTop = "true"
         android:layout_marginLeft = "10.0dip"  />
     < ImageView
         android:id = "@+id/radar_ray_3"
         android:layout_width = "70.0dip"
         android:layout_height = "70.0dip"
         android:layout_alignParentRight = "true"
         android:layout_alignParentTop = "true"
         android:layout_marginLeft = "10.0dip"  />
</ RelativeLayout >

程序主入口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package  com.zhf.android_ripple;
import  android.os.Bundle;
import  android.app.Activity;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
public  class  MainActivity  extends  Activity {
                                                                   
     public  Button m_btn1;
     AnimationFrameLayout afl;  //动画布局
     @Override
     protected  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
                                                                       
         afl = ((Animat ionFrameLayout) findViewById(R.id.search_animation_wf_main)); // 搜索时的动画
         m_btn1 = (Button) findViewById(R.id.button1);
         m_btn1.setOnClickListener( new  OnClickListener() {
             @Override
             public  void  onClick(View v) {
                 afl.startAnimation();
             }
         });
     }
                                                                   
     @Override
     protected  void  onDestroy() {
         // TODO Auto-generated method stub
         super .onDestroy();
         afl.stopAnimation();
     }
}


ok! 源码已添加!试试效果吧!






     本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1334425,如需转载请自行联系原作者





相关文章
|
XML 移动开发 ARouter
为什么说Flutter让移动开发变得更好?Android篇
为什么说Flutter让移动开发变得更好?Android篇
为什么说Flutter让移动开发变得更好?Android篇
|
Web App开发 移动开发 前端开发
Android面试:为什么说Flutter让移动开发变得更好?全套教学资料
Android面试:为什么说Flutter让移动开发变得更好?全套教学资料
|
移动开发 Android开发