本节内容对应《第一行代码 第三版》:第三章
文章目录
- 一、在AndroidManifest中注册
- Manifest简介
的用处 - 二、Activity导航
- 1.显式导航
- 2.隐式Intent
- 3.传递数据
- 三、菜单
- 四、Activity的生命周期
- 五、 在Activity被回收时保存数据
- 六、Activity的启动模式
- 七、kotlin标准函数with/run/apply
- 八、Kotlin中的静态方法
如果我们创建了一个空的项目(no activity),自己新建了一个FirstActivity,此时需要在Manifest中手动注册。
幸运的是,AS已经为我们写好了以下代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lrgy.activitytest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".FirstActivity">
</activity>
</application>
</manifest>
其中,com.lrgy.activitytest表示应用整体的包名,android:name=".FirstActivity"表示这个application具体注册了com.lrgy.activitytest.FirstActivity这个Activity。
我们需要指定程序运行时首先启动哪个Activity,即在
标签中添加
标签
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
这两个标签指明了应用启动时首先启动该Activity
另外,
这个标签还有额外的作用,即在里面添加
、
、标签
· intent介绍见:Intent 和 Intent 过滤器
val intent = Intent("com.lrgy.activitytest.ACTION_START")
传入的参数相同即可<action android:name="com.lrgy.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
标签中添加tools:ignore="AppLinkUrlError"
<activity android:name=".ThirdActivity">
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW"/>'
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="https"/>
intent-filter>
activity>
//构建Intent对象,参数:上下文Context,目的地Activity
val intent = Intent(this, SecondActivity::class.java)
//执行intent
startActivity(intent)
val intent = Intent("com.lrgy.activitytest.ACTION_START")//传入要响应界面的action值
intent.addCategory()//传入要响应界面的category值,也可以不设置,即默认
startActivity(intent)
val intent = Intent(Intent.ACTION_VIEW) //内置动作,跳转至其他应用
intent.data = Uri.parse("https://baidu.com") //接受Uri对象,设置目的uri
startActivity(intent)
发送:
intent.putExtra("extra_data", "携带的信息")
接收:
intent.getStringExtra("extra_data")
接受:
startActivityForResult(intent,10086)//带有返回结果的导航,10086是请求码,在这里设置
//重写onActivityResult方法,requestCode是请求码,resultCode是处理结果如RESULT_OK,data是回传的Intent
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode){
10086 -> Log.d("mydebug", "收到下层反馈")
}
}
发送:
//按下返回键即调用该方法
override fun onBackPressed() {
super.onBackPressed()
val intent = Intent()
intent.putExtra("data_return","返回给上层的数据")
setResult(RESULT_OK,intent)//第一个参数是向上返回结果,用RESULT_OK就行
finish()
}
指定菜单项<item
android:id="@+id/add_item"
android:title="Add"/>
//创建菜单,即在Activity中重写该方法
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
//传入menu资源和要添加至的Menu对象,后者一般用onCreateOptionsMenu中自带参数menu
menuInflater.inflate(R.menu.main, menu)
//return true才能显示菜单
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId){
//使用toast弹出框。参数:上下文上下文Context、显示内容、常量LENGTH_SHORT或Toast.LENGTH_LONG
R.id.add_item -> Toast.makeText(this,"add item",Toast.LENGTH_SHORT).show()
R.id.remove_item -> Toast.makeText(this,"remove item",Toast.LENGTH_LONG).show()
}
/*关于返回值
有人说:
* true表示该方法执行完毕后,点击事件不会再向下一个事件处理方法传递了。
* false表示执行完该方法后,点击事件继续向下传递。
* */
return false
}
详解见:Android Activity生命周期详解
fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle)
这个函数将会在Activity被回收前调用,我们可以把数据存放在outState: Bundle
中。
override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
super.onSaveInstanceState(outState, outPersistentState)
val tempData = "something you want to save"
outState.putString("data_key",tempData)
}
然后在onCreate
中使用savedInstanceState: Bundle?
取出数据
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
savedInstanceState?.let {
Log.d(tag,it.getString("data_key"))
}
}
PS:关于手机屏幕旋转导致Activity重建的问题,我们有更优雅的解决方法,在13.2节
通过在AndroidManifest.xml
中的
标签可以指定启动方式
<activity
android:name=".FirstActivity"
android:launchMode="standard">
activity>
val list = listOf<String>("apple", "banana", "pear", "orange")
val builder = StringBuilder()
builder.append("start eating fruits...\n")
for (fruit in list){
builder.append(fruit).append("\n")
}
builder.append("ate all fruits.")
val result = builder.toString()
println(result)
val result2 = with(StringBuilder()){
append("start eating fruits...\n")
for (fruit in list){
append(fruit).append("\n")
}
append("ate all fruits.")
toString()
}
println(result2)
val result3 = StringBuilder().run{
append("start eating fruits...\n")
for (fruit in list){
append(fruit).append("\n")
}
append("ate all fruits.")
toString()
}
println(result3)
val result4 = StringBuilder().apply{
append("start eating fruits...\n")
for (fruit in list){
append(fruit).append("\n")
}
append("ate all fruits.")
}
println(result4.toString())
object Util {
fun doAction(){
println("do action")
}
}
class Util {
companion object{
fun doAction(){
println("do action")
}
}
}
JvmStatic
(真静态方法)class Util {
companion object{
@JvmStatic
fun doAction(){
println("do action")
}
}
}
package com.lrgy.activitytest
fun doAction(){
println("do action")
}
在Kotlin中直接用方法名调用,JAVA中用文件名Kt.方法名
调用