- 创建activity,每一个activity都需要重新配置gradle,所以就需要修改我们build——gradle中的仓库。因为Android开发逻辑和视图分开的,而且每一个activity都要有一个对应的layout布局,所以在res中创建一个对应的.xml,,用于设计逻辑的视图。
- <Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="main Button" />
这个是在.xml中添加一个button中出来的,我们可以直接拖进,也可以在.xml中直接进行手动编写。Id是唯一标识符,主要语法结构是@+id/实际id。
在Xml布局中进行设计之后,我们需要在对应的要现实的Activity逻辑中添加这个页面布局。
在activity中添加布局使用setContentView(R.layout.布局的名字),加载一个布局。
- 现在是编写好的Activity,以及它对应的布局,并且把布局插入在activity中,两个是必须成对的,一个负责逻辑一个负责视图设计
- 所有的Activity都必须在AndroidMainfest.xml中进行才注册才可以进行生效,而其实已经自动进行注册了,在application中有:
<activity android:name=".FirstActivity"></activity>
可以就看出,已经配置好了,FirstActivity已经配置进来了,
但是此时我们需要思考一个问题,就是进入时,哪个是主进入页面。就是说,哪一个是MainActivity。在activity中使用如下: 就可以设置fristActivy是主activity。
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
总结:想要编写用户可以看到的页面,就是activity,不过activity中只编写逻辑,设计布局在对应的res-layout中创建一个对应的xml文件,用于书写这个界面的视图,然后将布局加载入activity中,这样才能对应起来。
然后需要把activity注册进入AndroidMainfest.xml,然后设置哪一个是进入的主页面,使用<intent-filter>在activity中指定这个是主进入的页面。
Ps:如果没有设置主进入的activity,无法在启动器中看到,一般是作为第三方服务供其他应用使用。
- 自己设计的一个逻辑:
- 使用toast,这个就是类似于弹窗的,会在触发事件触发后弹窗给用户,并在一定时间后消失。
//在activity中编写逻辑,所以我们想使用toast的话,需要在activity中编写逻辑,设置触发事件。
//将页面上的button设置为触发事件,如果进行触发就会弹窗
val button:Button = findViewById(R.id.button)
//通过调用setOnClickListener为这个button创建一个监听器,点击按钮时就会执行监听器中的onclick的方法,
//所以弹出toast的功能就要在onclick中进行编写
button.setOnClickListener {
//在makeText中是由三个参数的,第一个是context,也就是toast显示的上下文,因为activity就是一个context,所以写this就可以
//第二个是显示内容,第三个是显示的时间,一般就两个
Toast.makeText(this,"this is toast",Toast.LENGTH_SHORT).show()
}
- 认识第一个第三方库 ButterKnife ,
目的是为了在使用获取布局中的控件,比如说刚刚是按照id获取到button,使用的是findviewbyid,获取到一个继承于view的泛型对象。如果要是要获取的是很多的控件就很不方便。第三方库就是为了简化操作,【因为Android项目中已经自动引入了插件,】这个插件的方便之处就是,它自动根据布局文件中定义的控件id自动生成一个相同名字的对象,所以就不用再findviewbyid了,直接拿控件id来进行操作就行。
所以上面的可以修改为:
button.setOnClickListener {
Toast.makeText(this,"this is toast",Toast.LENGTH_SHORT).show()
}
【自己这里是没有加入插件的,所以,一会看看如何插入插件?】
- 学习menu
Menu也是类似于layout。在res创建一个menu的包,所有关于menu的设计都在这里写,然后在对应的activity中加载进去。这里是一个xml中写的,
//这里用item来创建两个菜单项,id是唯一标示,title是这个菜单项的名称
<item
android:id="@+id/add_item"
android:title="add"/>
<item
android:id="@+id/remove_item"
android:title="remove"/>
然后我们在要使用这个menu的activity中编写逻辑,使用这个menu。在使用menu的activity中重写onCreateOptionsMenu方法,在这个的方法中menuInflater实际上是调用的是父类的getmenuInflater方法,返回一个menuInflater对象,这个再调用inflate方法,就可以给当前的activity创建菜单。参数两个,第一个是指定通过哪一个资源文件来创建菜单,第二个参数是指定菜单项将添加到哪一个menu对象当中,这里就是用oncreateOptionsMenu中传过来的参数【这里为什么用传进来的参数,而且这个方法在哪里调用,调用的时候才知道这个参数是啥?】
return true表示的是使用菜单,显示出菜单。
//在这个activity中使用menu,重写如下的方法
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,"click add",Toast.LENGTH_SHORT).show()
R.id.remove_item -> Toast.makeText(this,"click remove",Toast.LENGTH_SHORT).show()
}
return true
}
总结:上面是学习了使用菜单,使用的时候肯定第一步是设计一个menu,所以创建了一个menu的包,在下面创建一个菜单,如上的main菜单,菜单里面有两个item,
接下来是要在activity中显示这个菜单,重写了oncreateoptionMenu方法,显示出来这个菜单。
最后,因为菜单显示出来,我们是要操作菜单,所以设计了菜单的响应事件,重写了onOptionItemSelected的方法,当item.itemid是add_item,则进行产生一个toast,显示“click add”同理是remove。
- 学习使用Intent在Activity中穿梭【】
这里创建了一个新的Activity,secondActivity,步骤已经会了,设计对应的布局文件,并在activity中加载进来,在xml中将secondActivity配置进来【这一步现在是自动进行的】。
SecondActivity不是主进入的界面,所以不用配置<intent-filter>。
学习使用intent,学习之前要先知道它能干啥,是各个组件之间进行交互的方式,可以指明当前的组件想要执行的动作,也可以在不同组件之间传递信息。可以分为:显示intent和隐式intent
使用:【这个是显式intent,直接指明启动Activity的上下文,也指明了要启动的Activity】
//在不同的Activity之间进行跳转,点击button3将会跳转到secondactivity,
// Intent()有两个参数,第一个参数是启动Activity的上下文,第二个参数是想要启动的的Activity
//将生成的 Intent对象,将其传入startActivity中作为参数,这个方法是专门用于启动Activity的。
val button3 :Button = findViewById(R.id.button3)
button3.setOnClickListener {
val intent = Intent(this,SecondActivity::class.java)
startActivity(intent)
}
【隐式intent 不指明要启动的是哪一个intent,而是指明了一系列的抽象的action 和category,你交给系统去分析,然后是系统找到合适的activity进行启动】
这里是在配置文件中,在配置secondActivity时,我们指明当前这个activity能够相应的action和category,这里就说明:这个Activity可以相应com.example.activitytest1.ACTION_START这个action
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.activitytest1.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
此时,我们是定义好secondactivity可以相应的action,如果说有一个activity中发生了这个action,则就会跳转这个activity中
val button3 :Button = findViewById(R.id.button3)
button3.setOnClickListener {
val intent = Intent("com.example.activitytest1.ACTION_START")
startActivity(intent)
}
这样的结果和上面的显式的intent执行效果一样。
我们不仅可以访问自己程序,还可以跳转到 其他的程序,比如说是其他的网址、
val button3 :Button = findViewById(R.id.button3)
button3.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.csdn.net/")
startActivity(intent)
}
下面这段是创建一个thirdactivity,在配置的时候指明当前这个activity可以相应的action是"android.intent.action.VIEW" 在data中指明数据的协议必须是https协议。这样这个activity就可以和浏览器一样,能够响应一个打开网页的intent。
<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>
总结:刚刚这些是从一个activity中执行某一个动作跳转到某一个activity中或者是网页中,可以使用显式的intent或者使用隐式intent。
如果说两个Activity之间想要传递数据,
(1)Activity传递参数
intent提供的有一系列的putExtra方法的重载,我们需要传递数据的时候,就先把数据保存在intent中,然后在启动了另个activity后就将数据从intent中取出就可以。
putExtra方法传递了两个参数,一个是键,用于在跳转之后的activity中取值用,第二个是真正传过去的值。
val button3 :Button = findViewById(R.id.button3)
val str :String = "hello SectionActivity"
button3.setOnClickListener {
val intent = Intent(this,SecondActivity::class.java)
intent.putExtra("data",str)
startActivity(intent)
}
在SecondActivity中使用这个传过来的值,
val data = intent.getStringExtra("data")
Log.d("SecondActivity","data id $data")
在secondActivity中获取到这个值,并在控制台输出。
(2)返回数据给上一个Activity,
在firstActivity中,并且使用的是startActivityForResult来启动新的activity,这个方法会返回来值。
val button3 :Button = findViewById(R.id.button3)
//val str :String = "hello SectionActivity"
button3.setOnClickListener {
val intent = Intent(this,SecondActivity::class.java)
//intent.putExtra("data",str)
startActivityForResult(intent,1)
}
在SecondActivity中设置一个点击事件,将数据传回上一个activity,数据存在intent中,
val button2 :Button = findViewById(R.id.button2)
button2.setOnClickListener {
val intent = Intent()
intent.putExtra("data_return","udhsufufguiof")
setResult(RESULT_OK,intent)
finish()
}
setResult方法是专门用于向上传递参数的,两个参数,第一个是向上一个Activity返回处理结果,有两个可用的值(RESULT_OK 和 RESULT_canceled),第二个是intent,将带有数据的intent传回去。
Finish是销毁这个activity,不然是跳不过去原来的activity的
这样就从secondactivity中返回到firstactivity中,但是此时first中实际上是没有接收second传过来的数据,我们可以重写一个onActivityForResult方法,
- 关于Activity的生命周期
自己创建了三个页面,在主页面中可以通过按钮,然后跳转到其他的两个页面,可以发现在打印出的日志中
package com.example.activitylifecycletest
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
class MainActivity : AppCompatActivity() {
private val tag = "mainactivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(tag,"oncreate")
setContentView(R.layout.activity_main)
val normalbutton:Button = findViewById(R.id.startNormalButton)
normalbutton.setOnClickListener {
val intent = Intent(this,NormalActivity::class.java)
startActivity(intent)
}
val dialogbutton :Button = findViewById(R.id.startDialogButton)
dialogbutton.setOnClickListener {
val intent = Intent(this,DialogActivity::class.java)
startActivity(intent)
}
}
//重写各种控制生命周期的方法
override fun onStart() {
super.onStart()
Log.d(tag,"onstart")
}
override fun onResume() {
super.onResume()
Log.d(tag,"onresume")
}
override fun onPause() {
super.onPause()
Log.d(tag,"onpause")
}
override fun onStop() {
super.onStop()
Log.d(tag,"onstop")
}
override fun onDestroy() {
super.onDestroy()
Log.d(tag,"ondestory")
}
override fun onRestart() {
super.onRestart()
Log.d(tag,"onRsatrt")
}
}