Android学习路线_入门篇(二)四大组件之Acitvity

Android应用开发中核心的四大组件是整体应用的骨架,利用好四大组件才能搭建出一个合理高效的APP。我们先来了解一下四大组件中必备的组件——Activity,它是用户交互的入口,也是程序效果展示的出口,它是应用界面的基石。

本文已收录至☞Android学习路线_梳理
上一篇☞Android学习路线_入门篇(一)编写简单的APP
下一篇☞Android学习路线_入门篇(三)Acitvity生命周期与启动模式

1. 创建一个Activity

在上一篇文章中我们已经有了一个自动生成的MainActivity,那么这一次我们就来详细介绍一下Activity该如何手动创建,必须依赖的文件和代码有哪些。

1.1 注册机制

首先我们先来看一下AndroidManifest.xml文件,在上一篇文章中我们已经对它有了一点了解。

AndroidManifest是我们APP的清单文件,四大组件为什么会被归类到一起,就是因为它们四个都是必须在清单文件中注册的(广播例外,还可以在代码中动态注册),这里我们先只看看Activity的注册。

相信你已经注意到了,自动为我们生成的代码中有一段明显是Activity相关的:

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    intent-filter>
activity>

上述代码中有几个关键的点:

  • 标签,标志着一个Activity相关的注册配置,通过name属性指定对应的类文件,格式可以是完整的路径,也可以省略应用的包名(第三方包名不可以省略)。
  • 标签,信使过滤器,除了启动时展示的第一个Acitivty外不是必须要有的标签,目前这一段代表的意义就是这是启动的第一个Activity,第二节我们会详细介绍信使intent。

再介绍一下标签中目前没看见但以后你可能用到的属性:

  • label设置Activity的标题,默认情况下顶部导航栏会展示当前Activity对应label的值,如果没有设置则展示Application对应的label值。
  • theme设置Activity的主题,可以在styles.xml文件中配置各种样式。
  • configChanges设置Activity在指定事件变化时触发onConfigurationChanged()方法,而不是重新启动。
  • launchMode设置Activity的启动模式,下一篇文章会详细介绍启动模式。
  • taskAffinity指定Activity所在的页面栈。

1.2 类与布局

完成注册配置以后,我们还需要一个类文件和一个布局文件。

类文件是Activity详细的逻辑代码,用于控制界面视图的展示效果、处理用户的输入数据、触发具体的业务功能。

package com.example.myapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

在自动生成的MainActivity类中,可以看到包名package和导入import,这里遵循基本的java语法。MainActivity继承了AppCompatActivity,同时重写了onCreate()方法并调用了父类方法,在onCreate()方法中调用了setContentView()方法绑定布局文件activity_main.xml

再来看看布局文件activity_main.xml


<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

androidx.constraintlayout.widget.ConstraintLayout>

首先固定的,以及根布局中固定属性xmlns:android="http://schemas.android.com/apk/res/android"

根布局默认是,这是谷歌主推的约束布局,之后会在介绍控件时了解到各种布局。

根布局属性xmlns:app="http://schemas.android.com/apk/res-auto"是在使用扩展属性时用到的,可以注意到系统内置属性开头都是android:,扩展属性开头根据前面的扩展声明决定,比如这里就是app:开头。

layout_width是宽度指定,layout_height则是高度指定,值可以是具体值,单位通常是dp,比如10dp;也可以是match_parent父布局尺寸、wrap_content自适应尺寸。

布局内部只有一个元素,文本框控件text属性指定文本内容,可以是直接的文案,但通常都是在strings.xml文件中预设文本元素,布局中可通过@string/的方式引用。app:开头的四个属性则是约束布局用来约束文本框位置和大小的。

控件和布局相关的内容之后会再出文章详细介绍,感兴趣的小伙伴可以先关注我哦~。

2. Activity相互跳转

现在我们知道了一个Activity必须要有的东西,这时候我们已经可以自己创建一个新的Activity了!但是问题来了,我怎么才能看到这个新建的Activity呢?

2.1 跳转Activity

首先我们要有一个新的Activity,先在AndroidManifest里的application中增加一段Activity的注册信息吧:

<activity android:name=".SecondActivity">
activity>

这时候有报错提醒,别急,再在src/main/java/com/example/myapplication/路径新建一个类SecondActivity:

package com.example.myapplication

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
    }
}

还是有报错提醒对吧,缺少的布局文件得补上,路径是src/main/res/layout/activity_second.xml


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Second Activity"/>

FrameLayout>

这下我们有了新的SecondActivity,怎么在APP中展示出来呢?我们先给MainActivity中加一个点击事件,更改layout_main.xml文件的TextView,加上id方便我们找到它,更改一下文本:

......
    <TextView
        android:id="@+id/tv_go_to_second"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go to Second!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
......

再去MainActivity中设置点击事件:

package com.example.myapplication

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        tv_go_to_second.setOnClickListener { 
            startActivity(Intent(this, SecondActivity::class.java))
        }
    }
}

可以注意到这一行代码是核心的跳转逻辑:

startActivity(Intent(this, SecondActivity::class.java))

这时候运行APP,点击屏幕中间的“Go to Second”文本就可以跳转到SecondActivity了,使用屏幕左上角的返回按钮或者设备的返回按钮就能够返回MainActivity了。

2.2 信使Intent

我们可以看到上一小节中用到了Intent,它是四大组件传递信息的信使,启动一个Activity就需要靠它。

Intent有特别多的构造方法,比较常用的有:

  • Intent(Context packageContext, Class cls)显式跳转Activity使用,packageContext是当前的上下文信息(通常是当前Activity),cls是目标Activity的类。
  • Intent(String action, Uri uri)隐式启动四大组件使用,action是指明动作意图,uri则是跳转附带参数。还记得之前的标签,就是用来过滤隐式Intent的过滤器,这时候只有的内容与action参数保持一致时才可以启动对应的组件,可以跨APP启动。

Intent常用的方法:

  • addCategory(),这里设置的参数就是与标签的内容保持一致时有效。
  • putExtra(),这里设置的参数可以在接收数据的类中通过getExtra()方法拿到。

2.3 跳转后返回带数据

有时候从第一个Activity跳转到第二个Activity后,当从第二个返回第一个时需要传递一些数据给第一个Activity,这时还是需要通过Intent来传递。

首先,MainActivity调用的startActivity()方法应替换为startActivityForResult(),参数除了原有的Intent之外,还需要增加一个int类型的requestCode:

startActivityForResult(Intent(this, SecondActivity::class.java), 100)

其次,在MainActivity增加一个onActivityResult()方法,根据requestCode和resultCode来决定数据的处理:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == Activity.RESULT_OK && requestCode == 100) {
		// data是返回的Intent对象,可能为空,存有返回的数据
    }
}

最后,在我们的SecondActivity中增加调用方法:

setResult(Activity.RESULT_OK, Intent())

这样就可以顺利带上返回数据了。

完毕

今天的分享就到这里,文章多有不足,各位小伙伴有什么想法可以直接评论或是私信,要是对你有所帮助就给我一个赞吧,喜欢我的小伙伴可以关注我哦~

本文已收录至☞Android学习路线_梳理
上一篇☞Android学习路线_入门篇(一)编写简单的APP
下一篇☞Android学习路线_入门篇(三)Acitvity生命周期与启动模式

支持我的小伙伴们可以微信搜索“Android思维库”,或者微信扫描下方二维码,关注我的公众号,每天都会推送新知识~
在这里插入图片描述

你可能感兴趣的:(Android学习路线,android)