Android notes——第一行代码笔记(第三版)
Android notes——第一行代码笔记(第三版)
第3章——先从看得到的入手,探究Activity
3.1 Activity是什么
Activity是一种可以包含用户界面的组件
3.2 Activity基本用法
3.2.1-3.2.3 创建Activity、在Activity中加载layout布局、AndroidManifest中注册Activity
-
任何Acticity应该**重写onCreate() **方法,所有Activity中需要有一个主Activity。 -
最好每一个Activity都对应一个布局,讲究视图和逻辑分离。 -
布局文件最好使用驼峰命名法,例如:xxx_layout.xml -
项目中的任何资源都会在R文件中生成一个相应的资源id -
Activity和布局联系起来的方式
- 在Activity中加载first_layout.xml文件的布局
setContentView(R.layout.first_layout) class FirstActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.first_layout)
val button1: Button = findViewById(R.id.button1)
button1.setOnClickListener{
Toast.makeText(this, "You clicked Button 1", Toast.LENGTH_SHORT).show()
}
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.activitytest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" //在xml中不推荐直接出现字符串,而是在string.xml中做一个索引,所有字符串均在其中
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity android:name=".FirstActivity" android:label="This is FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
3.2.4 在Activity中使用Toast,Toast就是一个简单的提示消息~
Toast的用法:调用一个静态方法makeText() ,其参数如下:
参数 | 参数内容 |
---|
第一个 | Context对象,如果在Activity中使用,可以直接用this 关键字,因为Activity也是一个Context对象 | 第二个 | 文本,在""中键入显示的文本消息 | 第三个 | 文本停留时长,有Toast.LENGTH_SHORT 和Toast.LENGTH_LONG 两个参数 |
Toast.makeText(Context对象, "tpye your text here~", Toast.LENGTH_SHORT).show()
- 将调用静态方法
makeText() 的代码放入一个 调用监听器 的方法中,相应事件触发,即有相应提示。例子如下:
button1.setOnClickListener{
Toast.makeText(this, "You clicked Button 1", Toast.LENGTH_SHORT).show()
}
当button1被按下,则会有提示信息。
【注】控件和Activity联系的方式——在Activity中首先获取控件实例,然后为控件调用相应的监听方法
弃用的kotlin-android-extensions 插件,获取布局中定义的元素、获取控件等实例——findViewById() 的替代方法ViewBinding
findViewById() 方法获取布局文件中定义的元素,通过传入R.xxx 来得到相应控件的实例,但是在控件很多的情况下,这势必会变得枯燥且复杂。
就像这样:
val button1: Button = findViewById(R.id.button1)
......
val button100000: Button = ......
先前可以使用kotlin-android-extensions 插件来省略这一步P92,但是这一插件已经被弃用,具体内容见郭霖一篇关于kotlin-android-extensions插件弃用的博文,这里面详细叙述了在不同情况下使用ViewBinding 来替代kotlin-android-extensions 的方法。下面内容摘自郭霖的上面那篇博客
引用内容——郭霖大神的博客中内容,方便自己查阅~
ViewBinding总体来说其实非常简单,它的目的只有一个,就是为了避免编写findViewById,这和它另外一个非常复杂的兄弟DataBinding相比有明显的区别。
要想使用ViewBinding需要注意两件事。第一,确保你的Android Studio是3.6或更高的版本。第二,在你项目工程模块的build.gradle中加入以下配置:
android {
...
buildFeatures {
viewBinding true
}
}
这样准备工作就完成了。接下来我会从Activity、Fragment、Adapter、引入布局这4个方面,分别讨论ViewBinding的用法。
1.在Activity中使用ViewBinding
一旦启动了ViewBinding 功能之后,Android Studio会自动为我们所编写的每一个布局文件都生成一个对应的Binding 类。
Binding 类的命名规则是将布局文件按驼峰方式重命名后,再加上Binding 作为结尾。
比如说,前面我们定义了一个activity_main.xml布局,那么与它对应的Binding 类就是ActivityMainBinding 。
当然,如果有些布局文件你不希望为它生成对应的Binding 类,可以在该布局文件的根元素位置加入如下声明:
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
...
tools:viewBindingIgnore="true">
...
</LinearLayout>
接下来我们看一下如何使用ViewBinding 来实现在MainActivity 中去设置TextView 内容的功能,代码如下所示:【MHH注】TextView 是一个控件的id
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.textView.text = "Hello"
}
}
【MHH注】由上述可以看到,在val binding = ActivityMainBinding.inflate(layoutInflater) 和setContentView(binding.root) 这两行代码后,binding 可以直接获取layout中的元素id——textView
首先调用activity_main.xml布局文件对应的Binding类,也就是ActivityMainBinding的inflate()函数去加载该布局,inflate() 函数接收一个layoutInflater参数,在Activity中是可以直接获取到的。
接下来就更加简单了,调用Binding类的getRoot() 函数可以得到activity_main.xml中根元素的实例,调用getTextView() 函数可以获得id为textView的元素实例。
把根元素的实例传入到setContentView() 函数当中,Activity就可以成功显示activity_main.xml这个布局的内容了。然后获取TextView控件的实例,并给它设置要显示的文字即可。
当然,如果你需要在onCreate() 函数之外的地方对控件进行操作,那么就得将binding变量声明成全局变量,写法如下:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.textView.text = "Hello"
}
}
注意,Kotlin声明的变量都必须在声明的同时对其进行初始化。而这里我们显然无法在声明全局binding变量的同时对它进行初始化,所以这里又使用了lateinit 关键字对binding变量进行了延迟初始化。
2.在Fragment中使用ViewBinding
3.在Adapter中使用ViewBinding
4.对引入布局使用ViewBinding
3.2.5 在Activity中使用Menu——就是菜单啦!P92
res目录下new一个Directory——menu,右键menu文件夹,创建一个Menu resource file(第二行就是),命名为main
在main.xml的code中添加:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/add_item"
android:title="@string/add"/>
<item android:id="@+id/remove_item"
android:title="@string/remove"/>
</menu>
在Activity中重写onCreateOptionsMenu() 方法(ctrl + o快速定位)
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.main, menu)
return true
}
在Activity中重写onOptionsItemSelected() 方法,定义菜单响应事件
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.add_item -> Toast.makeText(this, "Add clicked", Toast.LENGTH_SHORT).show()
R.id.remove_item -> Toast.makeText(this, "Remove clicked", Toast.LENGTH_SHORT).show()
}
return true
}
3.2.6 销毁一个Activity
在相应控件的响应事件中加入如下代码:P96
finish()
3.3 使用Intent 在Activity之间穿梭
3.3.0何为intent
intent 是Android程序中各组件之间进行交互的一种重要方式
- 可以指明当前组件想要执行的动作
- 在不同组件之间传递数据
intent 一般用于启动
intent分为两种,显示intent 和隐式intent
Intent 有多个构造函数的重载,比如Intent(Context packageContext, Class<?> cls)
参数 | 描述 |
---|
第一个 | 要求提供一个启动Activity的上下文,上下文比较抽象(目前接触到的是使用当前的Activity,即this ) | 第二个 | Class用于指定想要启动的目标Activity,kotlin中可以这样使用:xxxx::class.java 相当于java中的xxxx.class ,以此来传入一个class对象 |
启动Activity的方法:startActivity() 方法,传入一个intent 对象,即可启动对应的目标Activity。
3.3.1使用显式Intent
使用3.3.0中使用的startActivity() 方法将启动一个Activity,按理来说,这个方法应该放在一些调用监听器的方法中,以便在相应控件监听到特定动作后,触发特定事件——启动一个Activity。下面给出郭霖书中的例子:
val binding = FirstLayoutBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.button1.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
按照上述例子的模式,需要启动的Activity放在了Intent(Context, class) 方法的第二个参数中,意图非常明显,所以书上称其为“显式Intent ”。
3.3.2使用隐式Intent
|