4.使用Intent传递数据(★★★★)
Intent可传递的数据类型有: 八大基本类型 ,数组,ArrayList<String>, Bundle 数据捆, 序列化接口(javabean)。
注意:Intent传递的数据过多可能会造成跳转速度极慢甚至黑屏一会,不要用Intent传递过多的数据,会影响到应用程序的使用。
下面通过一个案例来演示Intent如何传递数据,我们依然使用2.1 章节中的工程。需求:点击FirstActivity界面的按钮,将数据传递到SecondActivity,并显示传递的数据。
(1)修改AndroidManifest.xml文件中SecondActivity的intent-filter参数
两个页面间使用Intent传递数据
(2)在 FirstActivity 布局中添加一个按钮,给该按钮绑定事件,点击该按钮实现跳转到SecondActivity界面。该事件核心方法清单如下:
发送界面
(3)编写SecondActivity类,使其接收数据。
接收界面
(4)运行该工程,发现成功跳转到了SecondActivity界面,同时控制台也成功打印出了通过Intent传递数据。
5.案例-人品计算器(★★)
知识点:
1.跳转时使用startActivityForResult方法开启新页面
2.在被开启的新的页面里, 调用setResult方法设置回传的数据.
注意:设置完后不会立刻传递到前一个页面,而是等待当前页面关闭后, 才会回传数据。
3. 回传数据给传递给前一个页面的onActivityResult方法,在此方法中对数据进行处理即可。
需求:在MainActivity 页面中输入用户名,点击计算跳转到计算页面,计算页面计算完毕后将计算结果返回给MainActivity 界面,该界面将计算结果显示出来。
(1)创建一个新工程《人品计算器》,使用默认的Activity和默认的布局文件,修改布局文件。activity_main.xml布局清单如下:
布局文件
Tips:上面布局文件采用相对布局,其中android:background="@drawable/rp"属性是给界面设置背景图片,因此需要我们将图片添加到/res/drawable-hdpi目录下面。
android:visibility="invisible"属性是设置该控件不显示,显示的时候我们可以通过代码来实现其显示。
(2)编写MainActivity 核心代码类
public class MainActivity extends Activity { private TextView tv; private EditText et; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); et = (EditText) findViewById(R.id.et); } public void click(View view) { String data = et.getText().toString(); if (data == null || "".equals(data.trim()) || data.length() > 10) { Toast.makeText(this, "大哥,您输入的是人名吗?", Toast.LENGTH_SHORT).show(); et.setText(""); tv.setVisibility(View.INVISIBLE); return; } byte[] bytes = data.getBytes(); int result = 0; for (byte b : bytes) { result += b; } result = Math.abs(result % 101); // 创建一个新 Intent Intent intent = new Intent(this, CalcActivity.class); // 将数据绑定到 Intent 中 intent.putExtra("rp", result); // 打开一个新的 Activity,并接收器返回数据 请求码为 1,我们可以将请 求码理解为消息接应的暗号 startActivityForResult(intent, 1); } } /** * 当当前Activity用startActivityForResult方式调用另外一个Activity 的时候, * 另外一个 Activity 将数据返回后会 Android 系统会调用该方法 * */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //从当前 Intent 中获取数据 Bundle extras = data.getExtras(); String result = (String) extras.get("result"); //在也页面显示计算结果 tv.setVisibility(View.VISIBLE); tv.setText(result); } }
编写主界面代码
(3)新建CalcActivity 类继承Activity类,并在AndroidManifest.xml中添加该类。
public class CalcActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //获取当前 Intent Intent intent = getIntent(); //获取 Intent 中绑定的数据 Bundle extras = intent.getExtras(); //获取 rp int data = (Integer) extras.get("rp"); //计算人品结果 String result = getRPText(data); //创建一个新的 Intent Intent intent2 = new Intent(); //将结果绑定到 Intent 中 intent2.putExtra("result", result); //返回请求码和结果 setResult(1, intent2); //关闭当前 Activity finish(); } private String getRPText(int rp) { String rpText = null; if (rp == 0) { rpText = "你一定不是人吧?怎么一点人品都没有?!"; } else if (rp > 0 && rp <= 5) { rpText = "算了,跟你没什么人品好谈的..."; } else if (rp > 5 && rp <= 10) { rpText = "是我不好...不应该跟你谈人品问题的..."; } else if (rp > 10 && rp <= 15) { rpText = "杀过人没有?放过火没有?你应该无恶不做吧?"; } else if (rp > 15 && rp <= 20) { rpText = "你貌似应该三岁就偷看隔壁大妈洗澡的吧..."; } else if (rp > 20 && rp <= 25) { rpText = "你的人品之低下实在让人惊讶啊..."; } else if (rp > 25 && rp <= 30) { rpText = "你的人品太差了。你应该有干坏事的嗜好吧?"; } else if (rp > 30 && rp <= 35) { rpText = "你的人品真差!肯定经常做偷鸡摸狗的事..."; } else if (rp > 35 && rp <= 40) { rpText = "你拥有如此差的人品请经常祈求佛祖保佑你吧..."; } else if (rp > 40 && rp <= 45) { rpText = "老实交待..那些论坛上面经常出现的偷拍照是不是你的杰 作?"; } else if (rp > 45 && rp <= 50) { rpText = "你随地大小便之类的事没少干吧?"; } else if (rp > 50 && rp <= 55) { rpText = "你的人品太差了..稍不小心就会去干坏事了吧?"; } else if (rp > 55 && rp <= 60) { rpText = "你的人品很差了..要时刻克制住做坏事的冲动哦.."; } else if (rp > 60 && rp <= 65) { rpText = "你的人品比较差了..要好好的约束自己啊.."; } else if (rp > 65 && rp <= 70) { rpText = "你的人品勉勉强强..要自己好自为之.."; } else if (rp > 70 && rp <= 75) { rpText = "有你这样的人品算是不错了.."; } else if (rp > 75 && rp <= 80) { rpText = "你有较好的人品..继续保持.."; } else if (rp > 80 && rp <= 85) { rpText = "你的人品不错..应该一表人才吧?"; } else if (rp > 85 && rp <= 90) { rpText = "你的人品真好..做好事应该是你的爱好吧.."; } else if (rp > 90 && rp <= 95) { rpText = "你的人品太好了..你就是当代活雷锋啊..."; } else if (rp > 95 && rp <= 99) { rpText = "你是世人的榜样!"; } else if (rp == 100) { rpText = "天啦!你不是人!你是神!!!"; } else { rpText = "你的人品竟然负溢出了...我对你无语.."; } return rpText; } }
运行上面的工程,启动后页面左侧图,输入名字后点击计算,结果如右侧图。
6.Activity生命周期(★★★★)
Activity有三种状态:
1、当它在屏幕前台时,响应用户操作的Activity, 它是激活或运行状态
2、当它上面有另外一个Activity,使它失去了焦点但仍然对用户可见时, 它处于
暂停状态。
3、当它完全被另一个Activity覆盖时则处于停止状态。
当Activity从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:
方法名 | 说明 |
void onCreate() | 设置布局以及进行初始化操作 |
void onStart() | 可见, 但不可交互 |
void onRestart() | 调用 onStart() |
void onResume() | 可见, 可交互 |
void onPause() | 部分可见, 不可交互 |
void onStop() | 完全不可见 |
void onDestroy() | 销毁 |
Activity生命周期图:
1、startActivity开启一个Activity时, 生命周期的过程是:
onCreate ->onStart(可见不可交互) ->onResume(可见可交互)
2、点击back键关闭一个Activity时, 生命周期的过程是:
onPause(部分可见不可交互)->onStop(完全不可见)->onDestroy(销毁)
3、当开启一个新的Activity(以对话框形式), 新的activity 把后面的activity 给盖住一
部分时, 后面的activity的生命周期执行的方法是:
onPause(部分可见, 不可交互)
注:指定Activity以对话框的形式显示, 需在activity节点追加以下主题
android:theme="@android:style/Theme.Dialog"
4、当把新开启的Activity(以对话框形式)给关闭时, 后面的activity 的生命周期执
行的方法是:
onResume(可见, 可交互)
5、当开启一个新的activity把后面的activity完全盖住时, 生命周期的方法执行顺
序是:
onPause ->onStop(完全不可见)
6、当把新开启的activity(完全盖住)给关闭时, 生命周期的方法执行顺序是:
onRestart ->onStart ->onResume(可见, 可交互)
注意:实际工作中常用的方法以及应用场景有:
onResume 可见, 可交互.。把动态刷新的操作启动。
onPause 部分可见, 不可交互. 把动态刷新的一些操作, 给暂停了。
onCreate 初始化一些大量的数据。
onDestroy 把数据给释放掉, 节省内存。
6.1 横竖屏切换时 Activity 的生命周期
横竖屏切换时,默认情况下会把activity 先销毁再创建,在类似手机游戏这一类的应用中,这个体验是非常差的。不让 Activity 在横竖屏切换时销毁,只需要在清单文件声明
Activity时配置<activity>节点的几个属性即可,其方式如下:
4.0以下版本:android:configChanges="orientation|keyboardHidden"
4.0 以上版本:android:configChanges="orientation|screenSize"
兼容所有版本:android:configChanges="orientation|keyboardHidden|screenSize"