显而易见,window与Activity本身从名字上就知道不同,但对于项目开发中 windowAnimation和ActivityAnimation的区别必须心领神会。
区别主要如下
1.windowAnimation包括windowEnterAnimation和windowExitAnimation;ActivityAnimation包含android:activityOpenEnterAnimation,android:activityOpenExitAnimation,android:activityCloseEnterAnimation和android:activityCloseExitAnimation
2.在项目中WindowAnimation的控制权大于Activity的控制权,即在Activity转场过程中,如果同时设置了WindowAnimation和ActivityAnimation,那么可能(因为这种情况非常多)只会执行WindowAnimation
3.对于WindowAnimation的定义很简单,在style.xml文件中只需要继承Animation Style即可
1
2
3
4
5
6
|
<style name=
"Animation"
parent=
"@android:style/Animation"
>
<!--窗体进入动画-->
<item name=
"android:windowEnterAnimation"
>
@anim
/slide_left_enter</item>
<!--窗体退出动画-->
<item name=
"android:windowExitAnimation"
>
@anim
/slide_right_exit</item>
</style>
|
对于Activity,需要继承Animation Activity Style
1
2
3
4
5
6
|
<style name=
"FeelyouWindowAnimTheme"
parent=
"@android:style/Animation.Activity"
>
<item name=
"android:activityOpenEnterAnimation"
>
@android
:anim/slide_in_left</item>
<item name=
"android:activityOpenExitAnimation"
>
@android
:anim/slide_out_right</item>
<item name=
"android:activityCloseEnterAnimation"
>
@anim
/push_right_in</item>
<item name=
"android:activityCloseExitAnimation"
>
@anim
/push_left_out</item>
</style>
|
1
2
3
4
|
当我们从 A1 启动 A2 时,A1 从屏幕上消失,这个动画叫做 android:activityOpenExitAnimation
当我们从 A1 启动 A2 时,A2 出现在屏幕上,这个动画叫做 android:activityOpenEnterAnimation
当我们从 A2 退出回到 A1 时,A2 从屏幕上消失,这个叫做 android:activityCloseExitAnimation
当我们从 A2 退出回到 A1 时,A1 出现在屏幕上,这个叫做 android:activityCloseEnterAnimation
|
从上述2中动画的定义上来看,显然ActivityAnimation更为复杂,但这种复杂带来的转场效果非常好,可以同时控制2个Activity的动画,而不像WindowAnimation只能控制下一个Activity的窗体动画。
5.在开发中,窗体动画也可以使用 Activity.overridePendingTransition来设置,也可以定义在主题中,但Activity只能使用在主题中
1
2
3
4
5
6
7
8
9
10
|
<application
android:name=
"test.view.weitop.BaseApplication"
android:allowBackup=
"false"
android:hardwareAccelerated=
"false"
android:icon=
"@drawable/app_logo"
android:label=
"@string/app_name"
android:largeHeap=
"true"
android:theme=
"@style/Theme.App"
>
</application>
|
6.对于比较追求界面美感的动画,使用ActivityAnimation要好得多,因此对于一般开发使用windowAnimation即可,但对于追求用户体验,那么直接使用Activity Animation 吧
这里分享了一篇关于Activity动画的研究博客:http://www.oschina.net/question/97118_34343
-------------------------------------------------2014-12-27新增内容------------
Android布局动画,所谓布局动画并不是指专门作用在ViewGroup上的动画,而是作用到不居中的Child的有序动画
1.LayoutAnimationController --->第三方控件 WheelView的核心部分
1
2
3
4
5
|
ScaleAnimation sa =
new
ScaleAnimation(
0
.5f, 1f,
0
.5f, 1f, Animation.RELATIVE_TO_SELF,
0
.5f, Animation.RELATIVE_TO_SELF,
0
.5f);
sa.setDuration(
2000
);
LayoutAnimationController lac =
new
LayoutAnimationController(sa,
0
.5f);
lac.setOrder(LayoutAnimationController.ORDER_REVERSE);
rootView.setLayoutAnimation(lac);
|
2.android:animateLayoutChanges="true"
表示布局中childView的的大小改变,删除,增加时的 fade in 或者 fade out的动画
3.android:layoutAnimation="@anim/listview_anim"
android:layoutAnimation 和LayoutAnimationController作用类似,不同点在于,前者定义在xml中,后者使用代码编写
在iOS应用开发过程中,视图切换时的过渡动画是一个不可缺少的部分,简单的在Storyboard中托几个VC后连接上segue就可以实现,并可以选择几种如push,popover之类的动画效果,复杂的可以通过编码实现自定义的酷炫过渡动画效果(Github上有许多开源项目可以参考)。
最近一直在参研Android L的UI新特性,看到了更多注重UX的设计理解(当然也包括许多酷炫的效果,如OverScroll的新EdgeEffect、大部分控件的触摸效果,Reveal Effect等),其实从4.0 ICS开始,Android UI部分就有了很大的改进,当然也包括本篇要记录的过渡动画效果。4.0之前的UI动画主要是以Animation框架实现的,而4.0后加入了新的ObjectAnimator框架(貌似是3.0就有了,不过3.x是在没有存在感…),可以提供更多的动画控制从而实现更多的动画效果,这里记录下ObjectAnimator XML动画资源用于Activity和Fragment切换过渡动画的基本方法。
ObjectAnimator是以对一系列可变属性,如位移、旋转、缩放、Alpha等的改变来实现动画效果的,既可以使用写代码也可以使用定义XML资源文件的方式完成,这里以XML资源为例,在Android项目中存放于res/animator中,下面贴出几个简单动画效果示例:
card_flip_left_in.xml:
1 | <? xml version = "1.0" encoding = "utf-8" ?> |
5 | android:valueFrom = "1.0" |
7 | android:propertyName = "alpha" |
8 | android:duration = "0" /> |
12 | android:valueFrom = "-180" |
14 | android:propertyName = "rotationY" |
15 | android:interpolator = "@android:interpolator/accelerate_decelerate" |
16 | android:duration = "@android:integer/config_longAnimTime" /> |
20 | android:valueFrom = "0.0" |
22 | android:propertyName = "alpha" |
23 | android:startOffset = "@android:integer/config_mediumAnimTime" |
24 | android:duration = "1" /> |
card_flip_left_out.xml:
1 | <? xml version = "1.0" encoding = "utf-8" ?> |
7 | android:propertyName = "rotationY" |
8 | android:interpolator = "@android:interpolator/accelerate_decelerate" |
9 | android:duration = "@android:integer/config_longAnimTime" /> |
13 | android:valueFrom = "1.0" |
15 | android:propertyName = "alpha" |
16 | android:startOffset = "@android:integer/config_mediumAnimTime" |
17 | android:duration = "1" /> |
card_flip_right_in.xml:
1 | <? xml version = "1.0" encoding = "utf-8" ?> |
5 | android:valueFrom = "1.0" |
7 | android:propertyName = "alpha" |
8 | android:duration = "0" /> |
12 | android:valueFrom = "180" |
14 | android:propertyName = "rotationY" |
15 | android:interpolator = "@android:interpolator/accelerate_decelerate" |
16 | android:duration = "@android:integer/config_longAnimTime" /> |
20 | android:valueFrom = "0.0" |
22 | android:propertyName = "alpha" |
23 | android:startOffset = "@android:integer/config_mediumAnimTime" |
24 | android:duration = "1" /> |
card_flip_right_out.xml:
1 | <? xml version = "1.0" encoding = "utf-8" ?> |
7 | android:propertyName = "rotationY" |
8 | android:interpolator = "@android:interpolator/accelerate_decelerate" |
9 | android:duration = "@android:integer/config_longAnimTime" /> |
13 | android:valueFrom = "1.0" |
15 | android:propertyName = "alpha" |
16 | android:startOffset = "@android:integer/config_mediumAnimTime" |
17 | android:duration = "1" /> |
slide_down.xml:
1 | <? xml version = "1.0" encoding = "utf-8" ?> |
5 | android:interpolator = "@android:anim/accelerate_decelerate_interpolator" |
6 | android:propertyName = "translationY" |
7 | android:valueType = "floatType" |
10 | android:duration = "@android:integer/config_mediumAnimTime" /> |
slide_up.xml:
1 | <? xml version = "1.0" encoding = "utf-8" ?> |
5 | android:interpolator = "@android:anim/accelerate_decelerate_interpolator" |
6 | android:propertyName = "translationY" |
7 | android:valueType = "floatType" |
8 | android:valueFrom = "1280" |
10 | android:duration = "@android:integer/config_mediumAnimTime" /> |
有了animator资源在代码中就可以通过资源ID方式方便的使用了,对于Activity,要在startActivity后通过调用overridePendingTransition的方式来设置指定的过渡动画,如:
1 | startActivityForResult(intent, 100 ); getActivity().overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); |
两个参数分别为enterAnim和exitAnim,进入、退出动画。
相对而言,Fragment的过渡动画设置方法看着就要专业一些了,对FragmentTransaction调用setCustomAnimations即可,如下:
1 | FragmentTransaction ft = getFragmentManager().beginTransaction(); |
2 | ft.setCustomAnimations(R.animator.card_flip_left_in, |
3 | R.animator.card_flip_left_out, |
4 | R.animator.card_flip_right_in, |
5 | R.animator.card_flip_right_out); |
setCustomAnimations的声明是
1 | public abstract FragmentTransaction setCustomAnimations |
2 | ( int enter, int exit, int popEnter, int popExit) |
也有只有前两个参数的版本,后两个pop版为通过回退栈(back stack)触发的正反向动画。
PS:顺带一提使用Fragment时的Back键pop回退fragment栈中的fragment问题,本来以为在进行过fragment进栈操作后,会自动处理back键pop到没有为止,结果发现就算
1 | FragmentTransaction ft = getFragmentManager().beginTransaction(); |
2 | ft.setCustomAnimations(R.animator.card_flip_left_in, |
3 | R.animator.card_flip_left_out, |
4 | R.animator.card_flip_right_in, |
5 | R.animator.card_flip_right_out); |
6 | Fragment frag = SettingsFragment.newInstance(); |
7 | frag.setArguments( null ); |
8 | ft.replace(R.id.container, frag); |
9 | ft.addToBackStack( null ); |
这样addToBackStack后,当前Activity(我用的是ActionBarActivity)在响应back键时还是会执行默认的退出行为,而不是pop stack上的fragment先,这点可能在其它形式的fragment应用中,比如navigation drawer activity中会先pop吧,总之,这里我还是先通过override onBackPressed来处理了一下:
1 | public void onBackPressed() { |
3 | FragmentManager fm = getFragmentManager(); |
4 | if (fm.getBackStackEntryCount()> 0 ) { |
5 | fm.popBackStack( null , FragmentManager.POP_BACK_STACK_INCLUSIVE); |
这样就可以了。