Android Activity 数据传递
一个 App 一般都由多个 Activity 构成的,这就涉及到了多个 Activity 间数据传递的问题了
Activity 间的数据传递流程一般如下
-
一个传一个
存数据
Intent it1 = new Intent(A.this, B.class); it1.putExtra("key",value); startActivity(it1);
取数据
Intent it2 = getIntent(); getXxxExtra("key"); // Xxx 是数据类型
-
一次传多个
存数据
Intent it1 = new Intent(A.this, B.class); Bundle bd = new Bundle(); bd.putInt("num",1); bd.putString("detail","www.twle.cn"); it1.putExtra(bd); startActivity(it1);
取数据
Intent it2 = getIntent(); Bundle bd = it2.getExtra(); int n = bd.getInt("num"); String d = bd.getString("detail");
多个 Activity 间的交互 (后一个传回给前一个)
-
使用下面的方法启动一个
Activity
startActivityForResult(Intent intent, int requestCode)
-
在要启动的
Activity
中重写方法onActivityResult(int requestCode, int resultCode, Intent data);
参数 说明 requestCode 用于区分该 Activity
中不同的启动方式,比如有两个不同的按钮,启动的是同一个 Activity, 传递的数据可能不同,就可以使用 requestCode 来区分resultCode 子 Activity 通过 setResult()
放回的码 -
在子
Activity
中重写setResult(int resultCode, Intent data);
判断当前是哪个 Activity
如果要判断当前是那个 Activity
,只需要让所有的 Activity
继承一个自定义的 BaseActivity
然后在 onCreate()
方法中添加以下语句
Log.d("BaseActivity",getClass().getSimpleName());
随时关闭所有 Activity
有时我们可能会打开了很多个Activity,突然来个这样的需求,在某个页面可以关掉 所有的Activity并退出程序
这种情况下,可以使用一个 list 集合来存储所有 Activity ,要关闭的时候遍历所有的 Activity 然后逐一关闭
步骤如下
-
创建一个
Activity
管理器类ActivityCollection
,并定义三个public
的静态方法存储 Activity 的list
集合方法 说明 addActivity() 往集合列添加 Activity 对象 removeActivity() 从集合中移除 Activity 对象 finishAll() 增强 for
循环遍历所有的Activity
,调用 `if(! activity.isFinishing()) activity.finish() -
在
BaseActivity
中-
onCreate()
方法添加ActivityCollection.addActivity(this);
-
onDestory()
方法中添加ActivityCollection.removeActivity(this);
-
可以在任意一个
Activity
中调用下面的方法关闭所有的Activity
ActivityCollection.finishAll();
-
ActivityCollection 代码如下
public class ActivityCollection { public static LinkedList<Activity> activities = new LinkedList<Activity>(); public static void addActivity(Activity activity) { activities.add(activity); } public static void removeActivity(Activity activity) { activities.remove(activity); } public static void finishAll() { for(Activity activity:activities) { if(!activity.isFinishing()) { activity.finish(); } } } }
完全退出 App 的方法
添加下面的代码,可以在退出的时候杀死整个 App,连后台任务都杀死 杀得一干二净的
/** * 退出应用程序 */ public void AppExit(Context context) { try { ActivityCollector.finishAll(); ActivityManager activityMgr = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); activityMgr.killBackgroundProcesses(context.getPackageName()); System.exit(0); } catch (Exception ignored) {} }
双击返回键退出程序
要实现双击返回键退出程序,有两种方法
-
定义一个变量,来标识是否退出
// 定义一个变量,来标识是否退出 private static boolean isExit = false; Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); isExit = false; } }; public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (!isExit) { isExit = true; Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show(); // 利用handler延迟发送更改状态信息 mHandler.sendEmptyMessageDelayed(0, 2000); } else { exit(this); } return false; } return super.onKeyDown(keyCode, event); }
-
保存点击时间
//保存点击的时间 private long exitTime = 0; public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if ((System.currentTimeMillis() - exitTime) > 2000) { Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show(); exitTime = System.currentTimeMillis(); } else { exit(); } return false; } return super.onKeyDown(keyCode, event); }
Activity 转场动画
Activity 转场动画 就是切换到另外的 Activity 时加上一些切换动画,比如淡入淡出,放大缩小, 左右互推等
在这里我们并不讨论如何创建动画,而是提供了一些常用的过渡动画 Activity 常用过渡动画
, 只要将相关动画文件添加到 res/anim
目录下
然后可以通过下面两种方式实现 Activity 转场动画
-
代码设置 Activity 转场动画
A 跳转到 B,添加方式如下
startActivity( intent ); overridePendingTransition(R.anim.anim_in,R.anim.anim_out);
B 返回 A,添加方式如下
finish(); overridePendingTransition(R.anim.anim_in,R.anim.anim_out);
anim_in
是进入的Activity
的动画
anim_out
是退出的Activity
的动画 -
XML 方式设置 Activity 转场动画
通过 style 进行配置,这个是全局,就是所有的 Activity 都会加载这个动画
-
首先,在 style.xml 中定义 style
<!-- 默认 Activity 跳转动画 --> <style name="default_animation" mce_bogus="1" parent="@android:style/Animation.Activity"> <item name="android:activityOpenEnterAnimation">@anim/default_anim_in</item> <item name="android:activityOpenExitAnimation">@anim/anim_stay</item> <item name="android:activityCloseEnterAnimation">@anim/anim_stay</item> <item name="android:activityCloseExitAnimation">@anim/default_anim_out</item> </style>
4 个 item 分别代表
- Activity A 跳转到 Activity B 时 Activity B 进入动画
- Activity A 跳转到 Activity B 时 Activity A 退出动画
- Activity B 返回 Activity A 时 Activity A 的进入动画
- Activity B 返回 Activity A 时 ActivityB 的退出动画
-
然后修改 AppTheme
-
最后设置
AndroidManifest.xml
中的appliction
<application android:icon="@drawable/logo" android:label="@string/app_name" android:theme="@style/AppTheme" >
-
-
其它方式
转场动画除了上面两种方式外,还可以使用 TransitionManager 来实现,但最低版本必须是 API 19+
另外还有一种 addOnPreDrawListener 的转换动画,这个用起来还是有点麻烦的,你可以自行 baidu.com
Bundle 传递数据的限制
使用 Bundle 传递数据时,Bundle 的大小是有限制的 < 0.5MB ,如果大于这个值
是会报 TransactionTooLargeException
异常的
使用命令行查看当前所有 Activity
如果你为 SDK 配置了环境变量,则可以使用
adb shell dumpsys activity
设置 Activity 全屏
设置 Activity 全屏有两种方法
-
代码隐藏,在
onCreate()
方法中添加如下代码getActionBar().hide() //隐藏 ActionBar; requestWindowFeature(Window.FEATURE_NO_TITLE); //设置为无 title 模式 super.onCreate(savedInstanceState);
一定要注意顺序,不然会报错
-
通过
AndroidManifest.xml
的 `theme在需要全屏的 Activity 的标签内设置
theme = @android:style/Theme.NoTitleBar.FullScreen
onWindowFocusChanged 方法妙用
onWindowFocusChanged(boolean hasFocus)
当 Activity 得到或者失去焦点的时候,就会回调该方法
如果我们想监控 Activity 是否加载完毕,就可以用到这个方法了
想深入了解的可移步 onWindowFocusChanged触发简介
定义对话框 ( Dialog ) 风格的 Activity
某些情况下,可能需要将 Activity 设置成对话框风格的
Activity 一般是占满全屏的
Dialog 则是占据部分屏幕的
只要简单的设置 Activity 的 theme
android:theme="@android:style/Theme.Dialog"
也可以同时设置标题和小图标
//设置左上角小图标 requestWindowFeature(Window.FEATURE_LEFT_ICON); setContentView(R.layout.main); getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, android.R.drawable.ic_lion_icon); //设置文字: setTitle(R.string.actdialog_title); //XML 代码中设置:android:label="@string/activity_dialog"