工作好几年了,也没留下什么!所以想写点什么,算是对自己技术的一个总结,同时也希望给后来的Android开发学习者一些简单的参考。
老套路,有关Activity 的任何问题,欢迎在文章末尾或者我的公众号「aserbao」留言。知无不言…… 先看效果图(文末有源码地址):
Activity 是所以Android 初学者最先接触,也是必不可少需要接触的一个类,所以,作为 Android 学习系列的第一篇再好不过,别无其他理由。这是作为Activity系列最简单的一篇,只要不是初学者均可跳着看。
Activity 是Android中的一个活动窗口,Activity类主要负责在Android中创建一个与用户交互的窗口。
当我们通过Android Studio 创建项目的时候,项目会默认为我们创建一个MainActivity 的类,也就是我们的主界面。这篇文章主要讲Activity学习的第一步,Activity 的创建。
当启动Activity不需要回调我们可以调用 startActivity()方法,若需要从跳转的Activity返回数据,则通过调用startActivityForResult(~)来进行跳转,并将其传递给描述您想启动的 Activity 的 Intent 来启动另一个 Activity
我们可以通过startActivity() 来启动Activity,并且可以通过Activity 的Intent为跳转的Activity 提供少量的数据。
Intent intent = new Intent(this, LifeCycleActivity.class);
startActivity(intent);
我们也可以通过startActivityForResult(Intent intent, int requestCode)来启动Activity,这种方式启动可以获取跳转Activity退出后回传的结果数据。
Intent intent = new Intent(this, LifeCycleActivity.class);
startActivityForResult(intent,0);
当然,还有startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options)方法,我们在后面的Activity过渡动画界面会讲到。
standard
标准模式(也是Android默认的启动模式),在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。
例如: 若我有一个Activity名为A1, 上面有一个按钮可跳转到A1。那么如果我点击按钮,便会新启一个Activity A1叠在刚才的A1之上,再点击,又会再新启一个在它之上…… 点back键会依照栈顺序依次退出。(你启动多少个Activity,你就需要点击多少下返回键才能回主界面。)
singleInstance
单例模式,整个项目中有切只会存在一个Activity实例。当第二次调用的时候不会走Activity的onCreate()方法,会调用onNewIntent()方法。
例如:Task栈1的情况为:A B C。C通过Intent跳转到D,而D的Launch mode为singleInstance,则将会新建一个Task栈2。此时Task栈1的情况还是为:A B C。Task栈2的情况为:D。此时屏幕界面显示D的内容,如果这时D又通过Intent跳转到D,则Task栈2中也不会新建一个D的实例,而是调用D的onNewIntent()方法,所以两个栈的情况也不会变化。而如果D跳转到C,则栈1的情况变成了:A B C C,因为C的Launch mode为standard,此时如果再按返回键,则栈1变成:A B C。也就是说现在界面还显示C的内容,不是D。 按返回键,则栈1变成:A B C。也就是说现在界面还显示C的内容,不是D。
singleTop
栈顶复用模式,singleTop英文记忆,只有Activity在栈顶,才不会创建Activity的实例,会调用当前Activity 的onNewIntent()方法。若Activity不在栈顶,则和standard的启动模式一样。
例如:Task栈1中存在Activity A,B,C,若C的启动模式为singleTop,则从C跳转到C不会新建Activity实例,而是调用原先栈顶的C onNewIntent()方法。若B为SingleTop,C为standard,则从C跳转至B则会重新创建C的实例。
singleTask
栈内复用模式,singleTask 和singleInstance一样,均只有一个实例。不同点在于:在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent()方法。 如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。
属性taskAffinity
我们可以在manifest文件中对Activity进行taskAffinity属性配置,如:
具有相同taskAffinity值的Activity我们可以看做在一个任务内,若taskAffinity不相同,则在不同任务中。默认应用程序的taskAffinity值为包名。taskAffinity的值决定了当前Activity 的起始Activity(root Activity)。
Activity的Flag 的比较多,我们讲一下比较常用的:
使用方式:
Intent i =new Intent(this,StandardActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
过渡动画这里讲四种比较简单的过渡动画实现方式。
使用overridePendingTransition是比较常见的一种实现跳转动画的实现方式,首先我们来看下官方对于这个方法的解释:
/**
* Call immediately after one of the flavors of {@link #startActivity(Intent)}
* or {@link #finish} to specify an explicit transition animation to
* perform next.
*
* As of {@link android.os.Build.VERSION_CODES#JELLY_BEAN} an alternative
* to using this with starting activities is to supply the desired animation
* information through a {@link ActivityOptions} bundle to
* {@link #startActivity(Intent, Bundle)} or a related function. This allows
* you to specify a custom animation even when starting an activity from
* outside the context of the current top activity.
*/
public void overridePendingTransition(int enterAnim, int exitAnim) {
try {
ActivityManager.getService().overridePendingTransition(
mToken, getPackageName(), enterAnim, exitAnim);
} catch (RemoteException e) {
}
}
简单解释下上面的意思:
mAnimationPendingTopBtn.postDelayed(new Runnable() {
@Override
public void run() {
overridePendingTransition(R.anim.activity_left_to_screen_anim,R.anim.activity_screen_to_right_anim);
}
},1);
实例
我们做一个简单的从左至右的转场动画:我们从Activity A 跳转至Activity B ,Activity A从屏幕移到屏幕左边退出,Activity B 从屏幕右边移动到屏幕中!简单分析下步骤:
activity_right_to_screen_anim.xml代码如下:
overridePendingTransition(R.anim.activity_right_to_screen_anim, R.anim.activity_screen_to_left_anim);
WindowAnimation 有两种设置方式,一种是通过设置自定义主题Theme,还可以通过 getWindow().setWindowAnimations()方法去实现;在设置之前我们需要自定义动画文件(这里我们用上面创建好的动画文件),然后编辑一个自定义的style。方法如下:
简单讲解下属性内容:
区别:
定义好了style之后,我们将其设置到Activity上:
第一种:通过设置Theme:
设置Theme到对应的Activity即可。(这里注意,Activity的设置动画只有在Activity新建的时候才会有效果,比如将Activity的启动模式设置为singleInstance,只有第一次启动的时候有动画效果,后面每次跳转都是默认系统动画效果)。
第二种:通过getWindow().setWindowAnimations()方法设置
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setWindowAnimations(R.style.test_animation);
setContentView(R.layout.activity_base_animation);
}
需要注意的是: getWindow().setWindowAnimations()方法 和overridePendingTransition()方法一样,不能做任何延时操作,否则无效果。
ActivityOptions是Android 4.1(API 16)才添加的,但是使用时要求API >= 21,所以在使用的过程中需要注意适配问题。ActivityOptions 的使用很简单,我们只需要在启动Activity的时候调用startActivity(Intent intent, @Nullable Bundle options)方法,然后再通过getWindow().setEnterTransition(Transition transition)方法为跳转的Activity 指定特定的动画效果即可。
public static void launch(Activity activity, int type) {
Intent intent = new Intent(activity, BActivityOptionsActivity.class);
intent.putExtra(StaticFinalValues.TYPE, type);
activity.startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(activity).toBundle());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);//特别注意:此方法必须在setContentView之前调用,否则会报错,此方法注释有声明。
Transition explode = TransitionInflater.from(this).inflateTransition(android.R.transition.explode);
getWindow().setEnterTransition(explode);
setContentView(R.layout.activity_base_animation);
}
注意:getWindow().requestFeature()方法必须在setContentView之前调用,否则会报错。
共享动画属于Transition的一种,同样必须不低于API 21。使用方法如下:
public static void launch(Activity activity, View imageView) {
Intent intent = new Intent(activity, BShareModuleActivity.class);
activity.startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(activity, imageView, "aserbao_share_name").toBundle());
}
mShowActivityNameTv.setTransitionName("aserbao_share_name");
或者
android:transitionName="aserbao_share_name"
ok,两步搞定。
完整项目代码在AserbaosAndroid,如果觉得对你有用,帮忙点个star,谢谢各位。有问题请给我留言,知无不言。