03.活动Activity

1、活动是什么?

活动(Activity)是最容易吸引到用户的地方了,它是一种可以包含用户界面的组件(Android四大组件之一),主要用于和用户进行交互。一个应用程序中可以包含零个或多个活动,但不包含任何活动的应用程序很少见,谁也不想让自己的应用永远无法被用户看到吧?

2、活动的基本用法

到现在为止,我们还没有手动创建过活动呢,因为上一节中的MainActivity是Android Studio帮我们自动创建的。手动创建活动可以加深我们的理解,因此现在是时候应该自己动手了。

由于Android Studio在一个工作区内只能允许打开一个项目,因此首先我们需要将当前的项目关闭,点击导航栏File > Close Project。

然后再新建一个Android项目,项目名可以叫做ActivityTest,包名修改成我们自定义的com.sdbi.activitytest。

新建项目的步骤已经在上一节学习过了,不过我们这次要稍做修改,我们不再选择Empty Activity这个选项,而是选择No Activity,因为这次我们准备手动创建活动,如图所示。

点击Finish,等待Gradle构建完成后,项目就创建成功了。

1.手动创建活动

项目创建成功后,仍然会默认使用Android模式的项目结构,这里我们手动改成Project模式。

目前ActivityTest项目中虽然还是会自动生成很多文件,但是app/src/main/java/com.sdbi.activitytest目录应该是空的了,如图所示。

现在右击com.sdbi.activitytest包 > New > Activity > Empty Actity,会弹出一个创建活动的对话框,我们将活动命名为FirstActivity,并且不要勾选Generate Layout File和Launcher Activity这两个选项,如图所示。

勾选Generate Layout File表示会自动为FirstActivity创建一个对应的布局文件,勾选Launcher Activity表示会自动将FirstActivity设置为当前项目的主活动,这里由于你是第一次手动创建活动,这些自动生成的东西暂时都不要勾选,下面我们将会一个个手动来完成。点击Finish完成创建。

需要注意:项目中的任何活动都应该重写Activity的onCreate()方法,而目前我们的FirstActivity中已经重写了这个方法,这是由Android Studio自动帮我们完成的,代码如下所示:

package com.sdbi.activitytest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

可以看到,onCreate()方法非常简单,就是调用了父类的onCreate()方法。当然这只是默认的实现,后面我们还需要在里面加入很多自己的逻辑。

2.创建和加载布局

前面我们说过,Android程序的设计讲究逻辑和视图分离,最好每一个活动都能对应一个布局,布局就是用来显示界面内容的,因此我们现在就来手动创建一个布局文件。

右击app/src/main/res目录 > New > Directory,会弹出一个新建目录的窗口,这里先创建一个名为layout的目录。

然后对着layout目录右键 > Layout resource file,又会弹出一个新建布局资源文件的窗口,我们将这个布局文件命名为activity_first,根元素就默认选择为LinearLayout,如图所示。

点击OK完成布局的创建。这时候我们会看到布局编辑器

在窗口的右上方有3个切换卡,分别是Code、Split和Design。

  • Design模式是当前的可视化布局编辑器,在这里你不仅可以预览当前的布局,还可以通过拖拽的方式编辑布局。
  • Code模式是通过XML文件的方式来编辑布局。
  • Split模式会同时显示CodeDesign窗口。

现在点击一下Code切换卡,可以看到如下代码。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</LinearLayout>

由于我们刚才在创建布局文件时选择了LinearLayout作为根元素,因此现在布局文件中已经有一个LinearLayout元素了。

那我们现在对这个布局稍做编辑,添加一个按钮,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮1" />

</LinearLayout>

这里添加了一个Button元素,并在Button元素的内部增加了几个属性。

android:id是给当前的元素定义一个唯一标识符,之后可以在代码中对这个元素进行操作。你可能会对@+id/btn1这种语法感到陌生,但如果把加号去掉,变成@id/btn1,这你就会觉得有些熟悉了吧,这不就是在XML中引用资源的语法吗,只不过是把string替换成了id。是的,如果你需要在XML中引用一个id,就使用@id/id_name这种语法,而如果你需要在XML中定义一个id,则要使用@+id/id_name这种语法。

android:layout_width指定了当前元素的宽度,这里使用match_parent表示让当前元素和父元素一样宽。

android:layout_height指定了当前元素的高度,这里使用wrap_content,表示当前元素的高度只要能刚好包含里面的内容就行。

android:text指定了元素中显示的文字内容。切换到Split模式来预览一下当前布局,如图所示。

可以看到,按钮已经成功显示出来了,这样一个简单的布局就编写完成了。那么接下来我们要做的,就是在活动中加载这个布局。

重新回到FirstActivity,在onCreate()方法中加入如下代码:

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
    }
}

可以看到,这里调用了setContentView()方法来给当前的活动加载一个布局,而在setContentView()方法中,我们一般都会传入一个布局文件的id。

项目中添加的任何资源都会在R文件中生成一个相应的资源id,因此我们刚才创建的activity_first.xml布局的id现在应该是已经添加到R文件中了。我们只需要调用R.layout.activity_first就可以得到activity_first.xml布局的id,然后将这个值传入setContentView()方法即可。

3.在AndroidManifest文件中注册

别忘了前面我有说过,所有的活动都要在AndroidManifest.xml中进行注册才能生效,而实际上FirstActivity已经在AndroidManifest.xml中注册过了,我们打开app/src/main/Android-Manifest.xml文件瞧一瞧,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.sdbi.activitytest">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.ActivityTest"
        tools:targetApi="31">
        <activity
            android:name=".FirstActivity"
            android:exported="false"/>
    </application>

</manifest>

可以看到,活动的注册声明要放在<application>标签内,这里是通过<activity>标签来对活动进行注册的。

那么又是谁帮我们自动完成了对FirstActivity的注册呢?当然是Android Studio了。

很多人在使用Eeclipse创建活动或其他系统组件时,都会忘记要去Android Manifest.xml中注册一下,从而导致程序运行崩溃,Android Studio在这方面做得更加人性化。

在<activity>标签中我们使用了android:name来指定具体注册哪一个活动,那么这里填入的.FirstActivity是什么意思呢?其实这不过就是com.sdbi.activitytest.FirstActivity的缩写而已。由于在最外层的<manifest>标签中已经通过package属性指定了程序的包名是com.sdbi.activitytest,因此在注册活动时这一部分就可以省略了,直接使用.FirstAc-tivity就足够了。

不过,仅仅是这样注册了活动,我们的程序仍然是不能运行的,因为还没有为程序配置主活动,也就是说,当程序运行起来的时候,不知道要首先启动哪个活动。配置主活动的方法其实在之前已经介绍过了,就是在<activity>标签的内部加入<intent-filter>标签,并在这个标签里添加了<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />这两句声明即可。还有android:exported属性,它的主要作用是,设置 Activity 是否可由其他应用的组件启动, “true” 则表示可以,而“false”表示不可以。并且,启动的Activity就需要设置 exported 为 true。android:exported 是 Android中的四大组件 Activity,Service,Provider,Receiver 四大组件中都会有的一个属性。(从 Android 12 【即TargetSDK 31】开始,提高了app和系统的安全性)

除此之外,我们还可以使用android:label指定活动中标题栏的内容,标题栏是显示在活动最顶部的,待会儿运行的时候你就会看到。需要注意的是,给主活动指定的label 不仅会成为标题栏中的内容,还会成为启动器(Launcher)中应用程序显示的名称。

修改后的AndroidManifest.xml文件,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.sdbi.activitytest">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.ActivityTest"
        tools:targetApi="31">
        <activity
            android:name=".FirstActivity"
            android:exported="true"
            android:label="这是第一个活动">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

这样的话,FirstActivity就成为我们这个程序的主活动了,即点击桌面应用程序图标时首先打开的就是这个活动。

另外需要注意,如果你的应用程序中没有声明任何一个活动作为主活动,这个程序仍然是可以正常安装的,只是你无法在启动器中看到或者打开这个程序。这种程序一般都是作为第三方服务供其他应用在内部进行调用的,如支付宝快捷支付服务。

运行一下程序,结果如图所示。

 

 

 在界面的最顶部是一个标题栏,里面显示着我们刚才在注册活动时指定的内容。

标题栏的下面就是在布局文件activity_first.xml中编写的界面,可以看到我们刚刚定义的按钮。

posted @ 2022-08-29 14:40  熊猫Panda先生  阅读(218)  评论(0编辑  收藏  举报