本节内容

1.搭建界面

2.实现界面之间跳转和传值

3.实现隐式跳转并回调数据

4.Log日志打印

5.Activity生命周期

6.记录界面旋转状态值

7.生命周期使用举例

一、搭建界面

1.先在activity_main.xml中布局一下页面,两个横线是Number控件,“+”“=”,还有后面的结果都是TextView,还要给Number控件添加两个id,分别为mFirst,mSecond,结果的控件为mResult.

2.在下方在添加两个按钮,用来进行界面的跳转。分别给它们设置一下id,为mNextBtn和mShareBtn。

3.整体用的是ConstraitLayout布局,可以自己调整布局一下。

image.png

4.再创建一个DetailActivity,然后在activity_detail里面简单布局一下,添加一个按钮即可,再给它添加一个id为mCalculateBtn。

image.png

二、实现界面之间的跳转和传值

1.首先给第一个页面的计算按钮添加点击事件,点击该按钮之后会跳转到另一个页面进行计算。

//给按钮添加点击事件
mNextBtn.setOnClickListener {
//跳转到下一个页面进行计算
//创建Intent
Intent().apply {
//设置值
putExtra("first",mFirst.text.toString().toInt())
putExtra("second",mSecond.text.toString().toInt())
//设置从哪个页面跳转到哪个页面
setClass(this@MainActivity,DetailActivity::class.java)
//跳转
startActivityForResult(this,123)
}
}

2.在DetailActivity里面获取传递过来的数据

//获取传递的Intent的数据
val first :Int = intent.getIntExtra("first",0)
val second:Int = intent.getIntExtra("second",0)

3.实现计算按钮的点击事件

//实现按钮的点击事件
mCalculateBtn.setOnClickListener {
//开始计算
val result= first + second
//将结果回调给上一个页面
Intent().apply {
putExtra("result",result)
}.also {
setResult(0,it)
}
//返回到上一个页面
finish()
}

4.因为要接收第二个页面回调过来的数据,所以在MainActivity里面需要重写一下onActivityResult()方法。需要判断一下回调来的是哪个请求。

//接收回调数据
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode==123){
data?.getIntExtra("result",0).also {
//将结果赋值到textView上
mResult.text = it.toString()
}
}else if(requestCode==456){
//分享页面返回回来的结果
data?.getStringExtra("ShareResult").also {
//弹出一个吐司,提示框
Toast.makeText(this,it,Toast.LENGTH_LONG).show()
}
}
}

三、实现隐式跳转并回调数据

1.重新创建一个工程,然后简易制作一个WeChat页面

image.png

2.顶部是一个TextView,可以设置一下背景颜色和字体颜色。可以给里面添加一个默认的文字,在code里面添加一个hint,设置默认文字为“分享内容:”。

3.在下方再添加一个按钮,设置id 为mBackBtn。(这个设置按钮是后面会另外加的,但是与这个小Demo无关)

4.由于是隐式跳转,所以需要给这个页面添加一个意图过滤器。在AndroidManifest.xml文件中的里面添加以下几行数据

5.再回到MainActivity,然后给分享按钮设置一下点击事件

//分享按钮事件
mShareBtn.setOnClickListener {
//使用隐式跳转到分享App的某个页面
Intent().apply {
action = "swl.WeChat"
data = Uri.parse("content: 今天的晚饭非常美味!!")
}.also {
startActivityForResult(it,456)
}
}

6.在Wechat工程的MainActivity页面里面接收一个传递过来的数据,即content.

//获取传递过来的数据
intent.data?.schemeSpecificPart.also {
//显示到textView中
mTextView.text = it
}

7.给返回按钮设置一下点击事件,一点击,就将结果返回给第一个Calculator页面。

//返回按钮
mBack.setOnClickListener {
//回调数据
Intent().apply {
putExtra("ShareResult","分享成功")
}.also {
setResult(1,it)
finish()
}
}

8.到上面为止,这个小demo就结束了。

四、Log日志打印

1.Log主要是用来调试代码,通过Logcat查看打印的日志内容,它有很多级别。打Log时会弹出一些提示,每一个都对应不一样的级别。

v - Verbose

d - Debug

i - Infer

e - Error

w - Warn

2.括号里面有两个参数。

tag - 用于设置过滤的标签,比较方便查找

message - 输出的内容

Android里的Log就类似于C里面的printf,都是打印。

五、Activity生命周期

1.生命周期本质上就是,界面从 创建→销毁 经历的过程。

onCreate: 当Activity被创建 需要对界面进行布局/初始化

onStart: 开始启动页面

onResume: 启动完毕 已经展现在用户面前 可以和用户进行交互了

onRestart: 重新启动,从后台到前台,又可以进行交互了

onPause: 当页面进行跳转时,前一个页面就会暂停交互

onStop:界面暂停了

onDestroy:界面销毁

2.程序状态不同时,调用的方法也不同。

程序第一次启动: onCreate→→ onStart→→ onResume

程序切换到后台:onPause→→onStop

程序从后台切换到前台: onRestart→→ onStart →→onResume

按返回键 当前界面会被释放掉: onPause→→onStop→→onDestroy

切换到其他页面:onPause→→onStop

程序从下一个页面切换回来: onRestart→→onStart→→onResume

当界面旋转时,会销毁当前页面 重新加载新的页面: onPause→→ onStop→→onDestroy→→onCreate→→onStart→→onResume

六、记录界面旋转状态值

1.在前面做的小demo中,我发现,当旋转界面时,这个页面会重新刷新,所以之前的数据都不复存在了。

2.在onCreate方法里面有一个bundle对象来记录程序的状态,当界面被销毁时会回调onSaveInstanceState方法,需要保存数据

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("content",mTextView.text.toString())
}

3.在MainActivity里面获取保存的数据

savedInstanceState?.getString("content","").also {
mTextView.text = it
}

七、生命周期使用举例

1.写一个实现流程类似高德地图的小demo。首先创建一个类。里面的方法并没有具体实现,只是模拟一下运行时的工作流程。

class GaodeMAp {
fun init(){
Log.v("map","初始化地图信息")
}
fun connect(){
Log.v("map","开始连接获取用户地理信息")
}
fun disConnect(){
Log.v("map","停止获取用户信息")
}
fun destroyInfo(){
Log.v("map","回收资源")
}
}

2.创建一个SecondActivity类,在里面创建一个对象

class SecondActivity : AppCompatActivity() {
private lateinit var map:GaodeMAp
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
//创建GaodeMap的对象
map= GaodeMAp()
//初始化
map.init()
}
override fun onResume() {
super.onResume()
//获取定位信息操作
map.connect()
}
override fun onPause() {
super.onPause()
//取消定位操作
map.disConnect()
}
override fun onDestroy() {
super.onDestroy()
map.destroyInfo()
}
}

3.lifecycle,可以通过它来监听某一个界面的生命周期。

创建一个类,继承自LifecycleObserver,主要是通过注解来实现感知界面的生命周期。

class GaodeMApLifecycle:LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun init(){
Log.v("map","初始化地图信息")
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connect(){
Log.v("map","开始连接获取用户地理信息")
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun disConnect(){
Log.v("map","停止获取用户信息")
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun destroyInfo(){
Log.v("map","回收资源")
}
}

4.在SecondActivity里面添加一个监听器,只需这一个操作,就可以监听前面的各种状态信息。和前面的代码实现的效果是一样的。

lifecycle.addObserver(GaodeMApLifecycle())

*当前的生命周期类中添加观察者,观察的对象是当前的lifecycle,观察者:GaodeMApLifecycle() 被观察者 lifecycle(SecondActivity),当被观察者的生命周期发生变化时,会主动去观察者中查询是否有观察这个周期。通过注解去观察。

关于lifecyle的工作原理

image.png

当调用Activity里面的方法时,它都会依次去询问一下监听器有没有被监听,然后就去前面的类里面找,如果没有,那么这个事件就不会回调。如果有,那么就执行对应的方法。