Android 对Path的旋转效果的拓展

 

  其实实现的思路就是利用Tween动画,通过对场景对象的不断变换(旋转,缩放,平移,改变透明度)效果来产生动画效果的。先来分析一下动画效果的形成,我们先把红色Button定义为一级菜单,弹出的子Button作为二级菜单。当点击一级菜单的时候,一级菜单旋转,同时弹出二级菜单。点击二级菜单,进入其他的Activity,不点击画面不变。点击一级菜单,二级菜单消失,一级菜单旋转到默认。所以就涉及到了一级菜单的旋转和二级菜单的缩放以及移动。

一级菜单的实现:

  可以采用两种方式来实现,一种是xml布局,另一种就是硬编码了。我们采用第一种方法来实现,这样也比较符合标准。一级菜单是一个旋转效果,所以用Tween动画里的Rotate(旋转)来实现,在这里我们使用xml来定义动画效果,这样比较符合官方标准。

 点击旋转动画:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
	android:fillEnabled="true"
	android:fillAfter="true">
	<rotate
	    android:fromDegrees="0"
	    android:duration="80"
	    android:toDegrees="-45"
	    android:pivotX="50%"
	    android:pivotY="50%"
	    android:interpolator="@android:anim/accelerate_decelerate_interpolator" >	    
	</rotate> 
</set>
点击回复动画:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
	android:fillEnabled="true"
	android:fillAfter="true">
	<rotate
	    android:fromDegrees="-45"
	    android:duration="80"
	    android:toDegrees="0"
	    android:pivotX="50%"
	    android:pivotY="50%"
	    android:interpolator="@android:anim/accelerate_decelerate_interpolator" >    
	</rotate>
</set>
  通过这两个xml文件就可以实现一级菜单的旋转效果了,下面来说二级菜单的弹出效果,因为在path里它是在程序的左下角弹出的,当我们使用Tween动画的translate (移动)时,需要指定初始坐标以及终止坐标,这样一来就要弄清楚Android屏幕的坐标系,它是从右上角开始从左到右从上到下,如图:


  我们的Button是从左下角弹出的,这样就可以根据屏幕的分辨率来动态的设置菜单坐标。我的手机分辨率是800*480,就以这个来说明。然后我们来看一下Button移动的xml文件。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
	android:fillEnabled="true"
	android:fillAfter="true">
	<translate  
   		android:interpolator="@android:anim/cycle_interpolator"
    	android:fromXDelta="0.0"
        android:toXDelta="50.0"
        android:fromYDelta="790"
        android:toYDelta="650.0"
        android:duration="80"
    	> 
	</translate> 
</set>
 这是最左边的那个Button,大家可以注意下坐标的设置。其他的xml文件就不展示了,原理和这个一样,只不过坐标不同。

  最后看一下Activity的实现,

package com.example.imitatepathdemo;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;
import android.widget.RelativeLayout.LayoutParams;

public class ImitatePatn extends Activity {

	private static Boolean isClick = false;
	private LayoutParams params = new LayoutParams(0, 0);
	private TextView refresh;
	private static int width, height;
	private Animation animationTranslate1,animationTranslate2,animationTranslate3, animationTranslate4,animationTranslate5,animationTranslate6,animationRotate1,animationRotate2, animationScale1,animationScale2;
	private Button buttonCamera, buttonDelete, buttonWith, buttonPlace, buttonMusic, buttonThought, buttonSleep;
	private Intent intent1,intent2,intent3,intent4,intent5,intent6;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_imitate_patn);
        refresh=(TextView) this.findViewById(R.id.refresh);
        refresh.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				Intent intent=new Intent(ImitatePatn.this,SleepActivity.class);
				startActivity(intent);
			}
		});
        initialButton();
    }

	private void initialButton() {
    	Display display = getWindowManager().getDefaultDisplay(); 
		height = display.getHeight();  
		width = display.getWidth();
		Log.v("width  & height is:", String.valueOf(width) + ", " + String.valueOf(height));
		
		//padding是控件的内容相对控件的边缘的边距. 
		//margin是控件边缘相对父控件,或者其他控件的边距.
    	
    	buttonSleep = (Button) findViewById(R.id.button_composer_sleep);	
		
		
		buttonThought = (Button) findViewById(R.id.button_composer_thought);
		
		
		buttonMusic = (Button) findViewById(R.id.button_composer_music);
	
		
		buttonPlace = (Button) findViewById(R.id.button_composer_place);
		
		
		buttonWith = (Button) findViewById(R.id.button_composer_with);
		

		buttonCamera = (Button) findViewById(R.id.button_composer_camera);
		
		
		buttonDelete = (Button) findViewById(R.id.button_friends_delete);		
		
		
		animationScale1=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.scale_animation1);
		animationScale2=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.scale_animation2);
		
    	buttonDelete.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				//一级菜单旋转,二级菜单弹出
				if(isClick == false){
					isClick=true;
					animationRotate1=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.rotate_animation1);
					buttonDelete.startAnimation(animationRotate1);			
					
					animationTranslate1=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation1);
					animationTranslate1.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;											
							params.setMargins(10, 500, 0, 0);
							buttonSleep.setLayoutParams(params);
							buttonSleep.clearAnimation();
							
						}
					});
					buttonSleep.startAnimation(animationTranslate1);
					
					animationTranslate2=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation2);
					animationTranslate2.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;
							params.setMargins(60, 510, 0, 0);
							buttonThought.setLayoutParams(params);
							buttonThought.clearAnimation();
						}
					});
					buttonThought.startAnimation(animationTranslate2);
					
					animationTranslate3=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation3);
					animationTranslate3.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;
							params.setMargins(110, 540, 0, 0);
							buttonMusic.setLayoutParams(params);
							buttonMusic.clearAnimation();
						}
					});
					buttonMusic.startAnimation(animationTranslate3);
					
					animationTranslate4=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation4);
					animationTranslate4.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;
							params.setMargins(150, 570, 0, 0);
							buttonPlace.setLayoutParams(params);
							buttonPlace.clearAnimation();
						}
					});
					buttonPlace.startAnimation(animationTranslate4);
					
					animationTranslate5=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation5);
					animationTranslate5.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;
							params.setMargins(175, 610, 0, 0);
							buttonWith.setLayoutParams(params);
							buttonWith.clearAnimation();
						}
					});
					buttonWith.startAnimation(animationTranslate5);
					
					animationTranslate6=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation6);
					animationTranslate6.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;
							params.setMargins(190, 660, 0, 0);
							buttonCamera.setLayoutParams(params);
							buttonCamera.clearAnimation();
						}
					});
					buttonCamera.startAnimation(animationTranslate6);
				}else{
					isClick=false;
					animationRotate2=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.rotate_animation2);
					buttonDelete.startAnimation(animationRotate2);
					
					animationTranslate1=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation7);
					animationTranslate1.setAnimationListener(new AnimationListener() { 
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;											
							params.setMargins(10, 790, 0, 0);
							buttonSleep.setLayoutParams(params);
							buttonSleep.clearAnimation();
							
						}
					});
					buttonSleep.startAnimation(animationTranslate1);
					
					animationTranslate2=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation8);
					animationTranslate2.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;											
							params.setMargins(10, 790, 0, 0);
							buttonThought.setLayoutParams(params);
							buttonThought.clearAnimation();
						}
					});
					buttonThought.startAnimation(animationTranslate2);
					
					animationTranslate3=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation9);
					animationTranslate3.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;											
							params.setMargins(10, 790, 0, 0);
							buttonMusic.setLayoutParams(params);
							buttonMusic.clearAnimation();
						}
					});
					buttonMusic.startAnimation(animationTranslate3);
					
					animationTranslate4=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation10);
					animationTranslate4.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							// TODO Auto-generated method stub
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;											
							params.setMargins(10, 790, 0, 0);
							buttonPlace.setLayoutParams(params);
							buttonPlace.clearAnimation();
						}
					});
					buttonPlace.startAnimation(animationTranslate4);
					
					animationTranslate5=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation11);
					animationTranslate5.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							// TODO Auto-generated method stub
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;											
							params.setMargins(10, 790, 0, 0);
							buttonWith.setLayoutParams(params);
							buttonWith.clearAnimation();
						}
					});
					buttonWith.startAnimation(animationTranslate5);
					
					animationTranslate6=AnimationUtils.loadAnimation(ImitatePatn.this, R.anim.translate_animation12);
					animationTranslate6.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							// TODO Auto-generated method stub
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;											
							params.setMargins(10, 790, 0, 0);
							buttonCamera.setLayoutParams(params);
							buttonCamera.clearAnimation();
						}
					});
					buttonCamera.startAnimation(animationTranslate6);
				}
			}
		});
    	
    	buttonSleep.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				buttonSleep.startAnimation(animationScale1);
				buttonPlace.startAnimation(animationScale2);
				buttonWith.startAnimation(animationScale2);	
				buttonCamera.startAnimation(animationScale2);	
				buttonMusic.startAnimation(animationScale2);
				buttonThought.startAnimation(animationScale2);
				buttonDelete.startAnimation(animationScale2);
				
			}
		});
    	
    	buttonThought.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				buttonThought.startAnimation(animationScale1);
				buttonSleep.startAnimation(animationScale2);
				buttonPlace.startAnimation(animationScale2);
				buttonWith.startAnimation(animationScale2);	
				buttonCamera.startAnimation(animationScale2);	
				buttonMusic.startAnimation(animationScale2);
				buttonDelete.startAnimation(animationScale2);
			}
		});
    	
    	buttonMusic.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				buttonMusic.startAnimation(animationScale1);
				buttonThought.startAnimation(animationScale2);
				buttonSleep.startAnimation(animationScale2);
				buttonPlace.startAnimation(animationScale2);
				buttonWith.startAnimation(animationScale2);	
				buttonCamera.startAnimation(animationScale2);	
				buttonDelete.startAnimation(animationScale2);
			}
		});
    	
    	buttonPlace.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				buttonPlace.startAnimation(animationScale1);
				buttonMusic.startAnimation(animationScale2);
				buttonThought.startAnimation(animationScale2);
				buttonSleep.startAnimation(animationScale2);
				buttonWith.startAnimation(animationScale2);	
				buttonCamera.startAnimation(animationScale2);	
				buttonDelete.startAnimation(animationScale2);
				
			}
		});
    	
    	buttonWith.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				buttonWith.startAnimation(animationScale1);
				buttonPlace.startAnimation(animationScale2);
				buttonMusic.startAnimation(animationScale2);
				buttonThought.startAnimation(animationScale2);
				buttonSleep.startAnimation(animationScale2);
				buttonCamera.startAnimation(animationScale2);	
				buttonDelete.startAnimation(animationScale2);
				
			}
		});
    	
    	buttonCamera.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				buttonCamera.startAnimation(animationScale1);
				buttonWith.startAnimation(animationScale2);
				buttonPlace.startAnimation(animationScale2);
				buttonMusic.startAnimation(animationScale2);
				buttonThought.startAnimation(animationScale2);
				buttonSleep.startAnimation(animationScale2);
				buttonDelete.startAnimation(animationScale2);
				
			}
		});
	}

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_imitate_patn, menu);
        return true;
    }

}
布局文件是:

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="fill_parent"
	android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
	android:background="#ffffff">

	<Button android:id="@+id/button_composer_sleep"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:background="@drawable/composer_sleep"
		android:layout_marginBottom="10dip" android:layout_marginLeft="10dip"
		android:layout_alignParentBottom="true">
	</Button>

	<Button android:id="@+id/button_composer_thought"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:background="@drawable/composer_thought"
		android:layout_marginBottom="10dip" android:layout_marginLeft="10dip"
		android:layout_alignParentBottom="true" android:layout_above="@id/button_composer_sleep">
	</Button>

	<Button android:id="@+id/button_composer_music"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:background="@drawable/composer_music"
		android:layout_marginBottom="10dip" android:layout_marginLeft="10dip"
		android:layout_alignParentBottom="true">
	</Button>

	<Button android:id="@+id/button_composer_place"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:background="@drawable/composer_place"
		android:layout_marginBottom="10dip" android:layout_marginLeft="10dip"
		android:layout_alignParentBottom="true" android:layout_above="@id/button_composer_music">
	</Button>


	<Button android:id="@+id/button_composer_with"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:background="@drawable/composer_with"
		android:layout_marginBottom="10dip" android:layout_marginLeft="10dip"
		android:layout_alignParentBottom="true" android:layout_above="@id/button_composer_place">
	</Button>


	<Button android:id="@+id/button_composer_camera"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:background="@drawable/composer_camera"
		android:layout_marginBottom="10dip" android:layout_marginLeft="10dip"
		android:layout_alignParentBottom="true" android:layout_above="@id/button_composer_with">
	</Button>


	<Button android:id="@+id/button_friends_delete"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:background="@drawable/friends_delete"
		android:layout_marginBottom="10dip" android:layout_marginLeft="10dip"
		android:layout_alignParentBottom="true" android:layout_above="@id/button_composer_camera">
	</Button>


</RelativeLayout>


 在Activity里,我们实例化菜单的Button对象,然后分别对他们实行动画效果。从xml文件可以看出,这些Button在一个相对布局的视图里堆叠在左下角,一级菜单在最上面,其他的在它的下面,所以刚开始我们只是看到一家菜单而已。从一级菜单Button的监听器里我们一方面实现了它本身的旋转,另一方面其他的Button也弹出。这里有一个很重要的地方需要强调一下,就是在旋转的动画里我们直接xml动画文件可以直接使用Button的监听器,什么意思呢,就是不管Button是否旋转,我们都可以去监听它。但是,这种情况不符合移动的Button,也就是我们的二级菜单,这个情况就是,点击一级菜单弹出二级菜单,但是之后你不能去响应二级菜单,点击没有任何反应。那怎么办呢,处理方法是我们使用setAnimationListener在这个监听器里,是这样处理的

animationTranslate2.setAnimationListener(new AnimationListener() {
						
						public void onAnimationStart(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationRepeat(Animation animation) {
							// TODO Auto-generated method stub
							
						}
						
						public void onAnimationEnd(Animation animation) {
							params = new LayoutParams(0, 0);
							params.height = 50;
							params.width = 50;											
							params.setMargins(10, 790, 0, 0);
							buttonThought.setLayoutParams(params);
							buttonThought.clearAnimation();
						}
					});

就是在动画结束的时候取消动画效果,不然动画状态会锁定,我们不能使用它!!到这里这个仿path的demo就到这里了,需要注意的地方一个是坐标的设定,这个其实还是布局麻烦的,对于不同分辨率的设备,我们需要设定不同的数值;然后就是要注意动画移动后如何去获取使用权,这个如果只用xml还是做不到,需要我们使用代码来辅助完成。效果如下:
 

  标题说到了是拓展,为什么呢,就是我们这个菜单可以放到其他的地方,可以做一个想ppt动画那样从上到下,淡入淡出等等的效果。实现原理和上面是一样的,大家可以发挥想象力,做出漂亮美观的程序。现在很多程序基本上都是静态的,我们可以像path这样,另辟蹊径,开启动态程序的大门,让我们的程序动起来!

 下载地址

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 84
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 84
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值