androidactivity动画
❶ Android转场动画一说
所谓转场动画,通俗的讲就是一个Activity跳转到另一个Activity是的动画。
Activity的转场动画很早就有了,5.0之前用的是overridePendingTransition()这个方法。在5.0之后,Google使用Material Design设计风格,进而有了的新的转场转场动画的诞生,效果还是挺炫酷的,下面我们先看下效果。
其实这里主要是靠overridePendingTransition(int enterAnim, int exitAnim)来加载动画,顾名思义第一个参数是进场动画,第二个是出场动画。
这几个效果是可以交互使用,比如进场用Fade效果,出场用SLide效果。也可以使用自定义的效果,这里不细说。当然5.0后了类似共享元素这类的效果那就另当别论了
说到这里不得不说Google在5.0MD设计中给我提供全新的过度动画ActivityOptions,以及兼容包ActivityOptionsCompat.下面来说一说它提供几种过度效果的方法
❷ 开发者选项窗口动画和过渡动画区别
窗口动画和过渡动画是指在窗口(activity或dialog)切换时的显示动画,窗口动画的范围相对较广,包括activity和dialog,而过渡动画只包括activity。
? 第一种方法是调用overridePendingTransition的方法,记得要在startActivity之前调用,还可以用startActivity(Intent, Bundle)设置Bundle来实现,这种可以跨Context,而overridePendingTransition只能在当前app内实现,具体做法是ActivityOptions.makeCustomAnimation(context, enterResId, exitResId).toBundle(),这种方法要求系统是4.1以后的。这两种方法实现的都是过渡动画。
? 前面这些方法都只能做activity的动画,要做dialog的动画,就必须用窗口动画。方法是设置style,然后dialog.getWindow().setWindowAnimations(R.style.MyStyle)或者dialog.getWindow().getAttributes().windowAnimations = R.style.MyStyle;这样就可以在弹出dialog的时候播放动画了。窗口动画也可以作用在activity上,style的设置一样,代码也差不多,直接在activity内就可以调用getWindow这条方法。style还有另外一种做法:
? 这种设置的是过渡动画,只对activity有用,对dialog没用。(除了用getWindow来设置动画资源外,还可以在你的Theme里添加一个item,item的name是android:windowAnimationStyle,然后指定上面的一种style)。
? 从原理上看,窗口动画和过渡动画其实就是系统在切换窗口时读取相应的动画资源,上面的所有做法本质上就是在替换那些资源。开发者需要处理的是如何选择,是窗口动画还是过渡动画。如果是dialog,只有窗口动画可选,也只能通过style来完成。如果是activity,就两种动画都可以,但大多情况下还是用过渡动画,因为通过像overridePendingTransition这些api可以很简单的实现,而如果想把动画应用到整个Activity,用style就更方便,至于用上面哪种style,其实没什么影响。
? 在实际的开发中,其实并不提倡用上面这些方法,因为手机的设置可以关闭这两种动画(在开发者选项那里),你没法保证app一定能显示动画。对于activity动画来说,可以在新的activity初始化结束后启动常规的动画,但这种方法要求你必须等到窗口的相关view初始化结束,但什么时候结束是无法预测的,这和手机性能有关,所以你可以设置定时器来播放,而对于dialog就没有其他解决的方法了。
❸ Android之Activity全面解析,有些知识点容易忘记
Activity作为安卓四大组件之一,是最重要也是用得最多的组件,涉及的知识点非常多,有些知识点平时开发很少用到,但在某些场景下需要特别注意,本文详细整理了Activity涉及的知识点,供开发参考。
针对Activity可以提出很多问题,如:
Activity 的生命周期?
Activity 之间的通信方式?
Activity 各种情况下的生命周期?
横竖屏切换时 Activity 的生命周期?
前台切换到后台,然后再回到前台时 Activity 的生命周期?
弹出 Dialog 的时候按 Home 键时 Activity 的生命周期?
两个Activity之间跳转时的生命周期?
下拉状态栏时 Activity 的生命周期?
Activity 与 Fragment 之间生命周期比较?
Activity 的四种 LaunchMode(启动模式)的区别?
Activity 状态保存与恢复?
Activity的转场动画有哪些实现方式?
Activity的生命周期中怎么获取控件宽高?
onNewIntent的执行时机?
如何连续退出多个Activity?
如何把Acitivty设置成Dialog样式 ,android:theme="@android:style/Theme.Dialog"
关于横竖屏切换的生命周期,对应不同的手机,由于厂商定制的原因,会有不同的效果,如设置了configChanges="orientation”在有些手机会执行各个生命周期,但有些手机却不会执行。
网上常见的结论如下:
但实际的测试如下:
可以看出,不同厂商的手机切屏生命周期会有差异。
从API 13以上,当设备在横竖切屏时,“屏幕尺寸”也会发生变化,因此为了杜绝切屏导致页面销毁重建,需要加上screenSize,使用设置4,即 android:configChanges="orientation|keyboardHidden|screenSize" .
Activity的四种状态如下:
在activity处于paused或者stoped状态下,如果系统内存紧张,可能会被销毁,当重回该activity时会重建,正常返回和被回收后返回的生命周期如下:
如果是回收后返回,onCreate的参数savedInstanceState不为空。
有哪些场景会触发onNewIntent回调呢?跟启动模式有关,首先该Activity实例已经存在,再次启动才可能触发。一种情况是启动模式是singleTask或者singleInstance,无论该activity在栈中哪个位置,都会触发onNewIntent回调,并且把上面其他acitivity移除,另一种情况是启动模式是singleTop或者以FLAG_ACTIVITY_SINGLE_TOP启动,并且该activity实例在栈顶,会触发onNewIntent,如果不在栈顶是重新创建的,不会触发。
在实际业务开发中,往往碰到需要连续退出多个activity实例,下面整理了几种常见方法:
● 发送特定广播
1、在需要处理连续退出的activity注册该特定广播;
2、发起退出的activity发送该特定广播;
3、接收到该广播的activity 调用finish结束页面。
● 递归退出
1、用startActivityForResult启动新的activity;
2、前一个页面finish时,触发onActvityResult回调,再根据requestCode和resultCode处理是否finish,达到递归退出的效果。
● FLAG_ACTIVITY_CLEAR_TOP
通过intent.setFlag(Intent.FLAG_ACTIVITY_CLEAR_TOP)启动新activity,如果栈中已经有该实例,则会把该activity之上的所有activity关闭,达到singleTop启动模式的效果。
● 自定义activity栈
1、自定义activity列表,新打开activity则加入栈中,关闭则移除栈;
2、需要退出多个activity时,则循环从栈中移除activity实例,并调用finish。
在讨论Activity启动模式经常提到任务栈,那到底什么是任务栈?
任务是一个Activity的集合,它使用栈的方式来管理其中的Activity,这个栈又被称为返回栈(back stack),栈中Activity的顺序就是按照它们被打开的顺序依次存放的。返回栈是一个典型的后进先出(last in, first out)的数据结构。下图通过时间线的方式非常清晰地向我们展示了多个Activity在返回栈当中的状态变化:
taskAffinity 任务相关性,可以用于指定一个Activity更加愿意依附于哪一个任务,在默认情况下,同一个应用程序中的所有Activity都具有相同的affinity, 名字为应用的包名。当然了,我们可以为每个 Activity 都单独指定 taskAffinity 属性(不与包名相同)。taskAffinity 属性主要和 singleTask 启动模式和 allowTaskReparenting 属性配对使用,在其他情况下没有意义。
taskAffinity 有下面两种应用场景:
分为显示启动和隐式启动。
(1)显示启动
直接指定待调整的Activity类名。
(2)隐式启动
Intent 能够匹配目标组件的 IntentFilter 中所设置的过滤信息,如果不匹配将无法启动目标 Activity。IntentFilter 的过滤信息有 action、category、data。
IntentFilter 需要注意的地方有以下:
● 一个 Activity 中可以有多个 intent-filter
● 一个 intent-filter 同时可以有多个 action、category、data
● 一个 Intent 只要能匹配任何一组 intent-filter 即可启动对应 Activity
● 新建的 Activity 必须加上以下这句,代表能够接收隐式调用
<category android:name="android.intent.category.DEFAULT" />
只要匹配一个action即可跳转,注意的是action要区分大小写。
规则:如果intent中有category,则所有的都能匹配到intent-filter中的category,intent中的category数量可用少于intent-filter中的。另外,单独设置category是无法匹配activity的,因为category属性是一个执行Action的附加信息。
intent不添加category会匹配默认的,即 “android:intent.category.DEFAULT”
如果上面例子,如果去掉intent.setAction("action_name"),则会抛出异常:
规则:类似action,但data有复杂的结构,只要匹配一个data并且与data中所有属性都一致就能匹配到Activity,只要有1个属性不匹配,都无法找到activity。
data的结构:
data 主要是由 URI 和 mimeType 组成的。
URI 可配置很多信息,的结构如下:
与url类似,例如:
mineType:指资源类型包括文本、图片、音视频等等,例如:text/plain、 image/jpeg、video/* 等
下面看下data匹配的例子:
只匹配scheme
只匹配scheme也是能匹配到activity的。
匹配scheme、host、port
将上面的data改为
匹配mineType
如果有mineType,则不能仅设置setData或setMineType了,因为setData会把mineType置为null,而setMineType会把data置为null,导致永远无法匹配到activity,要使用setDataAndType。
使用scheme的默认值contentfile
注意该方法需要在startAtivity方法或者是finish方法调用之后立即执行,不能延迟,但可以在子线程执行。
而在windowAnimationStyle中存在四种动画:
activityOpenEnterAnimation // 打开新的Activity并进入新的Activity展示的动画
activityOpenExitAnimation // 打开新的Activity并销毁之前的Activity展示的动画
activityCloseEnterAnimation //关闭当前Activity进入上一个Activity展示的动画
activityCloseExitAnimation // 关闭当前Activity时展示的动画
overridePendingTransition的方式比较生硬,方法也比较老旧了,不适用于MD风格,google提供了新的转场动画ActivityOptions,并提供了兼容包ActivityOptionsCompat。
我们知道在onCreate和onResume里面直接获取到控件宽高为0,那有什么办法获取到控件的实际宽高?只要有onWindowFocusChanged、view.post、ViewTreeObserver三种方式获取。
当用户点击桌面图标启动APP时,背后的流程如下:
我们看到的手机桌面是Launch程序的界面,点击应用图标会触发点击事件,调用startActivity(intent),然后通过Binder IPC机制,与ActivityManagerService(AMS)通讯,AMS执行一系列操作,最终启动目前应用,大概流程如下:
通过PackageManager的resolveIntent()收集跳转intent对象的指向信息,然后通过grantUriPermissionLocked()方法来验证用户是否有足够的权限去调用该intent对象指向的Activity。如果有权限,则在新的task中启动目标activity,如果发现没有进程,则先创建进程。
如果进程不存在,AMS会调用startProcessLocked创建新的进程,在该方法中,会通过socket的通讯方式通知zygote进程孵化新的进程并返回pid,在新的进程中会初始化ActivityThread,并依次调用Looper.prepareLoop()和Looper.loop()来开启消息循环。
创建好进程后下一步要将Application和进程绑定起来,AMS会调用上一节创建的ActivityThread对象的bindAppliction方法完成绑定工作,该方法会发送一条BIND_APPLICATION的消息,最终会调用handleBindApplication方法处理消息,并调用makeApplication方法处理消息,加载APP的classes到内存中。
通过前面的步骤,系统已经拥有了该Application的进程,后续的启动则是从已存在其他进程中启动Acitivity,即调用realStartAcitvityLocked,该方法会调用Application的主线程对象ActivityThread的sheleLaunchActivity方法,在方法中会发送LAUNCH_ACTIVITY到消息队列,最终通过handleLaunchActivity处理消息,完成Acitivty的启动。
Activity
Activity 的 36 大难点,你会几个?“建议收藏”
[译]Android Application启动流程分析
❹ Android动画一:Activity过渡动画详细实现原理
虽然 Android 5.0 之后推出了新的过渡动画方式,但通常只是用于特定的场合使用, activity.overridePendingTransition() 通用方式的过渡动画还是很常用。
overridePendingTransition有两个参数,第一个参数(enterAnim)是作用于SecondActivity 的 进入屏幕可见区域 效果,第二个参数(exitAnim)是作用于当前 Activity 离开屏幕可见区域 效果。
iOS 默认的效果,新的Activity从右边(R)数芦进入显示区域,当前Activity从左边离开显示区域到(L)。
enterAnim(activity_right_to_left_enter.xml):X轴从 100% 到 0
exitAnim(activity_right_to_left_exit.xml):X轴从 0 到 -100%
使用
一般从底部弹出新Activity,就是从B区域到屏幕可薯悔带见区域,当前的Activity是保持不变的。
enterAnim(activity_bottom_to_top_enter.xml):Y轴从 100% 到 0
exitAnim(no_anim.xml):Y轴保持不变
使用
前面讲了startActivity的转场动画,下面讲finish()的转场动画。overridePendingTransition有两个参数,第一个参数(enterAnim)是作用于上一个Activity的进入屏幕可见区域效果,第二个参数(exitAnim)是作用于当前哗前 Activity 离开屏幕可见区域效果。
iOS默认的finish动画,是当前的Activity从屏幕可见区域到R区域,上一个Activity从L区域到屏幕可见区域。
enterAnim(activity_left_to_right_enter.xml):X轴从 -100% 到 0
exitAnim(activity_left_to_right_exit.xml):X轴从 0 到 100%
使用
从屏幕底部滑出效果是,当前Activity从底部滑出屏幕可见区域,上一个Activity保持不变,和BottomIn不同的是,enterAnim是不需要使用动画,因为上一个Activity已经在屏幕的后面了,只需要改变当前Activity消失的效果。
exitAnim(activity_top_to_bottom_exit.xml):Y轴从 0 到 100%
使用
https://github.com/taoweiji/ActivityAnimationExample
❺ android 怎么将activity 退出的动画效果关闭
在AndroidMenifest.xml文件里面的Activity声明中,增加自己的Theme声明,如下:
<activity
android:name=".MyOrderListServiceActivity"
android:theme="@style/MyTheme"
>
在values的style.xml文件里 声明 一个style,起名为MyTheme,注意这里面有我自定义的东西,涉及到动画的声明,就只有 <item name="android:windowAnimationStyle">@style/AnimationActivity</item>这一项。
<style name="MyTheme">
<!-- float_box为我们定义的窗口背景 -->
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowAnimationStyle">@style/AnimationActivity</item>
</style>
在values的style.xml文件里 声明 一个style,起名为AnimationActivity,没错就是上面的MyTheme中的windowAnimationStyle的实现,如下:
<style name="AnimationActivity" mce_bogus="1" parent="@android:style/Animation.Activity">
<item name="android:activityOpenEnterAnimation">@anim/slide_in_bottom</item>
<item name="android:activityOpenExitAnimation">@anim/slide_out_bottom</item>
<item name="android:activityCloseEnterAnimation">@anim/slide_in_bottom</item>
<item name="android:activityCloseExitAnimation">@anim/slide_out_bottom</item>
</style>
添加完以上的内容,有的机器虽然进入的动画是可用的,但是退出的动画无效,还需要在你的Activity中添加一些代码,保证animation的完美运行
添加全局变量
protected int activityCloseEnterAnimation;
protected int activityCloseExitAnimation
在OnCreate里面添加如下代码:
TypedArray activityStyle = getTheme().obtainStyledAttributes(new int[] {android.R.attr.windowAnimationStyle});
int windowAnimationStyleResId = activityStyle.getResourceId(0, 0);
activityStyle.recycle();
activityStyle = getTheme().obtainStyledAttributes(windowAnimationStyleResId, new int[] {android.R.attr.activityCloseEnterAnimation, android.R.attr.activityCloseExitAnimation});
activityCloseEnterAnimation = activityStyle.getResourceId(0, 0);
activityCloseExitAnimation = activityStyle.getResourceId(1, 0);
activityStyle.recycle();
在你的程序finish之前,需要调用如下代码:
overridePendingTransition(activityCloseEnterAnimation, activityCloseExitAnimation);
我调用的例子如下:
@Override
public void finish() {
Log.i(TAG, "finish");
super.finish();
overridePendingTransition(activityCloseEnterAnimation, activityCloseExitAnimation);
}
这样就可以了。
❻ 安卓获取过渡动画实际时间
一般为1秒左右。
打开开发者模式,里面可以设置动画速度。
目前的App在安装后,第一次打开,都会显示两秒左右的logo,然后进入引导页。如果关闭App,再重新打开,则只会显示logo,然后直接进入主页。可以使用了Handler的postDelayed方法。把过渡动画的Activity设为默认启动的Activity。在当前Activity中,执行postDelayed方法,把延时的时长设为两秒即可。