为activity设置动画,除了在代码中用overridePendingTransition()方法外,还可以在清单文件中配置theme来实现。示例
清单文件中的配置为
android:theme="@style/mystyle"
如果写在
对于每一个activity来说,它只有打开和关闭两种状态。打开和关闭会有各自有两种情况,从A启动B时B就是进入,从B退回到A时A就是进入。从A启动B时A关闭,从B退回到A时B关闭。
其中的几个item的说明:
android:activityOpenEnterAnimation:当A打开B时,B的进入动画。因打开而导致的进入时的动画——open enter。
android:activityOpenExitAnimation:当A打开B时,A退出的动画。因打开而导致的关闭的动画——open exit。
android:activityCloseEnterAnimation:当B关闭时,A进入的动画。因关闭而导致的进入的动画——close enter。
android:activityCloseExitAnimation:当B关闭时,B的退出动画。因关闭而导致的退出动画——close exit。
弹出的菜单项可以通过activity来完成。效果:
其中拍照等就是一个activity界面。该activity的theme如下:
其中AnimBottom为:
attach():Activity在onCreate之前调用attach方法,在attach方法中会创建Window对象。window对象创建时并没有创建DecorView对象。用户在Activity中调用setContentView,该方法会调用Window的setContentView,这时会检查DecorView是否存在,如果不存在则创建DecorView对象,然后把用户自己的View 添加到DecorView中。这就是Activity显示界面的过程。
设置软键盘模式。主要解析adjustResize与adjustPan。前者重绘整个屏幕,会调用到View中的onSizeChanged()方法;后者不会重绘整个屏幕,它只是把屏幕中的组件进行平移,把获取焦点的组件显示出来即可,未获取焦点的则还会被软键盘遮盖。但是是adjustResize则不会。
adjustResize的图:
adjustPan的图:
从两个图可以看见:第一个图中(adjustResize)当软键盘弹起的时候,ListView会自动滚动到最后一个条目,因为它重绘了整个屏幕,相当于ListView重新加载一次。而第二个界面中(adjustPan),当软键盘弹起时,只是把当前屏幕中最后一个条目给顶起来,并不显示ListView中的最后一个条目。
它指明当前的activity所希望属于的栈。如果没有指定,就按
是否允许当前的activity重新宿主到具有相同的affinity的栈中,当该栈处于前台时。假设应用A有一个activityA的taskAffinity的值为com.example.demo1,且allowTaskReparenting为true;应用B有一个activityB的taskAffinity也为com.example.demo1。那么先运行应用A,运行后按小房子。再运行应用B,这时会发现显示的是activityA的内容。这是因为,activityA允许该activity重新宿主。因此,当activityB启动的时候,会建立一个affinity为com.example.demo1的栈,这个栈的affinity和activityA的taskAffinity一样,所以activityA就重新宿主(也就是移动到了activityB启动的栈中)了。再比如,应用A中启动了应用B的activityA(该activity的此属性值为true),那么当运行应用B时,显示的会是activityA(从应用A的task中重宿到应用B的task中)。
是否从最近浏览中删除。如果为true,则在最近浏览中无该应用图标,否则有。默认值为false。
是否允许别的应用程序打开该activity,true是允许。false是不允许。它的默认值是根据
在正常情况下,在一个activity调用finish()之前会调用onSavaInstanceState()用来保存该activity的状态,并会将它的状态存储到一个Bundle的对象中。当该activity再次启动时,就会把该Bundle对象传到onCreate()方法中。如果该属性设置为true了,那么就不会调用onSavaInstanceState()方法,那么onCreate()方法中传入的参数就是null,就像该activity第一次被创建时一样。默认值是false。
当某个栈处于后台的时间过长,系统会自动回收这个栈中的除了根activity外的所有activity。如果在根activity设置了该属性并且值为true,那么这个栈中的所有activity都不会被系统回收,无论离开多长时间。
根activity该值为true,那么该栈中除了根activtiy外的所有activity,在该栈一进入后台的时候都会被清空。如果allowTaskReparenting与clearTaskOnLaunch都设置为true,那么在启动某一个栈的时候,该栈中能重新宿主的activity都会重新宿主,不能重新宿主的activity都会被清掉。该属性只对根activity设置有效,task中其它activity设置无效。
它和clearTaskOnLaunch类似,但是只能作用于一单个的activity,而不能作用于一个栈。当某一个activity的该属性值设置为true时,该activity所处的栈再次处于前台时,这个activity会finish掉,即使它设置了allowReparenting=true。
定义activity的启动模式有两种方式:清单文件和通过intent.setFlag()。如果两者同时存在,以后者为准。
标准启动模式。谁启动了该activity,那么该activity就会运行在启动它的activity所在的栈中。因此,在非activity中启动activity时,必须为intent设置FLAG_ACTIVITY_NEW_TASK标识,因为非activity没有任务栈。
参考
1. 设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的task是否存在;如果存在,它就会在这个任务中启动,否则就会在新任务栈中启动。因此,如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。这也可以解释为什么在同一个应用中启动singleTask的activity会是在同一个task,而不同应用中启动时却不是同一个task。因为默认时目标activity的taskAffinity为应用的包名,不同应用时taskAffinity与启动activity所在的task的affinity值不一致,因此目标activity会在新的task中启动。
2. 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。如果不存在,就新建一个目标activity的实例,并压入相应的task的顶端。
3,如果目标activity不是在新task中启动,那么目标activity所在的task会被挪移到前台,从而该task中的activity位于启动activity前面。如下:
文字说明为:A representation of how an activity with launch mode "singleTask" is added to the back stack. If the activity is already a part of a background task with its own back stack, then the entire back stack also comes
forward, on top of the current task.
新建一个栈,并将该activity放到该栈中,而且这个栈中不会放入别的任意的activity。
当启动模式为上述两种时,startActivityForResult()是无效的。onActivityResult()会立即执行,并且resultCode为RESULT_CANCELED。