完整代码Gitee地址:kotlin-demo: 15天Kotlin学习计划
第二天学习内容代码:Chapter2类
目录
知识点1:手动创建Activity
知识点2:Activity的基本用法
①Toast的使用
②Menu的使用
③隐式Intent的用法
④向下一个Activity传递数据
⑤返回数据给上一个Activity
⑥Activity被回收了怎么办
知识点3:随时随地退出程序
知识点4:启动Activity的最佳写法
知识点1:手动创建Activity
Activity是最容易吸引用户的地方,它是一种可以包含用户界面的组件,主要用于和用户进行交互。一个应用程序中可以包含零个或多个Activity。
1,手动创建Activity,继承AppCompatActivity,初始化onCreate方法;
package com.example.kotlin_demo
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class Learn2Activity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_learn2)
}
}
2,创建布局文件activity_learn2,并在onCreate里使用setContentView()方法引用;
创建布局文件activity_main,并增加点击按钮控件
3,新建的Activity都需要在AndroidManifest.xml里引用;
4,MainActivity布局增加点击按钮,并跳转Learn2Activity;5,设置themes.xml文件,DarkActionBar样式改为NoActionBar;
5,设置themes.xml文件,DarkActionBar样式改为NoActionBar;
运行效果:
知识点2:Activity的基本用法
①Toast的使用
Toast是Android系统提供的一种非常好的提醒方式,来看下Kotlin如何使用;
第一个参数是Context,也就是Toast要求的上下文,由于Activity本身就是一个Context对象,因此这里直接传入this即可。第二个参数是Toast显示的文本内容。第三个参数是Toast显示的时长,有两个内置常量可以选择:Toast.LENGTH_SHORT和Toast.LENGTH_LONG。
//①Toast的使用
val butToast: Button = findViewById(R.id.but_toast)
butToast.setonClickListener {
Toast.makeText(this, "Toast提示", Toast.LENGTH_SHORT).show()
}
②Menu的使用
由于menu是在ActionBar上的,这里需要把样式修改回来:
首先在res目录下新建一个menu文件夹,在menu文件夹→New→Menu resource file,新建main_menu.xml文件:
在Learn2Activity里重写onCreateOptionsMenu()方法
//创建菜单
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
//menuInflater使用了语法糖,它实际上是调用了父类的getMenuInflater()方法
//再调用它的inflate()方法,就可以给当前Activity创建菜单了
menuInflater.inflate(R.menu.main_menu, menu)
return true
}
仅仅让菜单显示出来是不够的,还要再定义菜单响应事件 ,在Learn2Activity里重写onOptionsItemSelected()方法
//菜单响应事件
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.add_item -> Toast.makeText(this, "增加用户", Toast.LENGTH_SHORT).show()
R.id.delete_item -> Toast.makeText(this, "删除用户", Toast.LENGTH_SHORT).show()
R.id.select_item -> Toast.makeText(this, "查看日志", Toast.LENGTH_SHORT).show()
}
return true
}
我们来看一下运行效果:
③隐式Intent的用法
val butIntent: Button = findViewById(R.id.but_intent)
butIntent.setonClickListener {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://blog.csdn.net/qq_30998053/category_11436257.html")
startActivity(intent)
}
④向下一个Activity传递数据
Intent中提供了一系列putExtra()方法的重载,可以把我们想要传递的数据暂存在Intent中,在启动另一个Activity后,只需要把这些数据从Intent中取出就可以了。在MainActivity跳转方法上增加putExtra方法,示例如下:
button.setonClickListener {
startActivity(Intent(this,Learn2Activity::class.java)
.putExtra("dataName","chapter2"))
}
在Learn2Activity中接收,代码如下:
val dataName = intent.getStringExtra("dataName")
Log.i("TAG", "dataName = $dataName")
输出结果为:
⑤返回数据给上一个Activity
在A界面MainActivity,使用startActivityForResult()方法,
startActivityForResult(
Intent(this, Learn2Activity::class.java)
.putExtra("dataName", "chapter2"), 9527
)
在B界面Learn2Activity增加一个返回按钮:
val butFinish: Button = findViewById(R.id.but_finish)
butFinish.setonClickListener {
val intent = Intent()
intent.putExtra("data_return","这是9527返回值")
setResult(RESULT_OK,intent)
finish()
}
但这样写,物理返回按键无法监听到,在onBackPressed返回方法中处理
override fun onBackPressed() {
super.onBackPressed()
val intent = Intent()
intent.putExtra("data_return","这是9527返回值")
setResult(RESULT_OK,intent)
}
最后在A界面MainActivity,并使用onActivityResult方法接收:
//第一个参数requestCode,即我们在启动Activity时传入的请求码;
//第二个参数resultCode,即我们在返回数据时传入的处理结果;
//第三个参数data,即携带着返回数据的Intent
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
9527 ->
if (resultCode == RESULT_OK) {
val data = data?.getStringExtra("data_return")
Log.i("TAG", "onActivityResult: $data")
}
}
}
打印结果为:
可以看到,我们在MainActivity中成功得到了从Learn2Activity传递过来的数据
⑥Activity被回收了怎么办
当一个Activity进入了停止状态,是有可能被系统回收的。打个比方,MainActivity中如果有一个文本输入框,现在你输入了一段文字,然后启动NormalActivity,这时MainActivity由于系统内存不足被回收掉,过了一会你又点击了Back键回到MainActivity,你会发现刚刚输入的文字都没了,因为MainActivity被重新创建了。
Activity中还提供了一个onSaveInstanceState()回调方法,这个方法可以保证在Activity被回收之前一定会被调用,代码示例:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val userName = "PeaceJay"
val userPwd = "123456"
outState.putString("userName", userName)
outState.putString("userPwd", userPwd)
}
数据是已经保存下来了,onCreate()方法其实也有一个Bundle类型的参数,那里进行恢复
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//恢复数据
if (savedInstanceState != null) {
val userName = savedInstanceState.getString("userName")
val userPwd = savedInstanceState.getString("userPwd")
Log.i("TAG", "恢复数据:userName=$userName userPwd=$userPwd")
}
}
知识点3:随时随地退出程序
新建一个单例类ActivityCollector作为Activity的集合,代码如下所示:
object ActivityCollector {
private val activityList = ArrayList()
//添加activity到集合
fun addActivity(activity: Activity) {
activityList.add(activity)
}
//从集合里面移除
fun removeActivity(activity: Activity){
activityList.remove(activity)
}
//关闭所有activity
fun finishAll(){
for (activity in activityList){
if (!activity.isFinishing){
activity.finish()
}
}
activityList.clear()
}
}
提供了一个addActivity()方法,用于向ArrayList中添加Activity;提供了一个removeActivity()方法,用于从ArrayList中移除Activity;最后提供了一个finishAll()方法,用于将ArrayList中存储的Activity全部销毁 。
接下来创建baseActivity,并添加与移除activity:
open class baseActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.i("baseActivity", javaClass.simpleName)
//添加activity
ActivityCollector.addActivity(this)
}
override fun onDestroy() {
super.onDestroy()
//销毁activity
ActivityCollector.removeActivity(this)
}
}
把MainActivity、Learn2Activity继承改为 baseActivity。
例如在Learn2Activity界面想通过点击按钮直接退出程序,如下所示:
val butAllFinish: Button = findViewById(R.id.but_all_finish)
butAllFinish.setonClickListener {
ActivityCollector.finishAll()
}
知识点4:启动Activity的最佳写法
比如Learn2Activity并不是由你开发的,但现在你负责开发的部分需要启动Learn2Activity,而你却不清楚启动Learn2Activity需要传递哪些数据。添加跳转页面模型,如下所示:
companion object {
fun actionStart(context: Context, data1: String, data2: String) {
context.startActivity(Intent(context,Learn2Activity::class.java)
.putExtra("data1",data1)
.putExtra("data2",data2)
)
}
}
在这里我们使用了一个新的语法结构companion object,并在companion object中定义了一个actionStart()方法。之所以要这样写,是因为Kotlin规定,所有定义在companion object中的方法都可以使用类似于Java静态方法的形式调用。
val butStart: Button = findViewById(R.id.but_start)
butStart.setonClickListener {
actionStart(this,"data1","data2")
}
养成一个良好的习惯,给你编写的每个Activity都添加类似的启动方法,这样不仅可以让启动Activity变得非常简单,还可以节省不少同事阅读代码时间。



