第一行代码Android----阅读笔记(第二章 探究活动_1)

第2章 探究活动_1

        活动是一种可以包含用户界面的组件,主要用于和用户进行交互。一个应用程序中可以包含零个或多个活动,但不包含任何活动的应用程序很少见。

2.2 活动的基本用法

        手动创建活动。Android Studio在一个工作区间内只允许打开一个项目,首先将当前项目关闭,点击导航栏File----Close Project。新建一个Android项目,项目名可叫作ActivityTest,包名默认,模版选择稍做修改,改为No Activity,准备手动创建活动,如图:

 2.2.1 手动创建活动

        项目创建成功后,手动更改项目结构为Project模式,以后所有项目均默认Project模式。查看app/src/main/java/com.example.activitytest目录是空的。如图所示:

        右击com.example.activitytest包----New----Activity----Empty Activity,会弹出一个创建活动的对话框,将活动命名为FirstActivity,并不勾选Generate a Layout File和Launcher Activity这两个选项,如图所示:

        勾选Generate a Layout File表示会自动为FirstActivity创建一个对应的布局文件,勾选Launcher Activity表示会自动将FirstActivity设置为当前项目的主活动。下面要手动创建,因为暂时不勾选。

        项目中的任何活动都应该重写Activity的onCreate()方法,目前FirstActivity中已经由Android Studio自动重写了这个方法,代码如下所示:

package com.example.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.2.2 创建和加载布局

        手动创建一个布局文件。右击app/src/main/res目录----New----Directory,会弹出一个新建目录的窗口,先创建一个名为layout的目录。然后对着layout目录右键----New----Layout resource file,又会弹出一个新建布局资源文件的窗口,将布局文件命名为first_layout,根元素默认选择为LinearLayout,如图:

        点击OK完成布局的创建,会看到如下图所示的布局编辑器。

        这是Android Studio提供的可视化布局编辑器,可以在屏幕中央区域预览当前的布局。窗口右上方有三个切换卡,Design是当前可视化布局编辑器,在这里不近可以预览当前的布局,还可以通过拖动的方式编辑布局。而Code是通过XML文件的方式来编辑布局,点击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/button_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 1"
        />

</LinearLayout>

        这里添加了一个Button元素,并在Button元素的内部增加了几个属性。android:id是给当前元素定义一个唯一标识符,之后可以在代码中对这个元素进行操作。第1章介绍过,在XML中引用一个id,就使用@id/id_name这种语法。如果需要在XML中定义一个id,则要使用@+id/id_name这种语法。android:layout_width指定了当前元素的宽度,match_parent表示让当前元素和父元素一样宽。android:layout_height指定了当前元素的高度,wrap_content表示当前元素的高度只要能刚好包含里面的内容就行。android:text指定了元素中显示的文字内容。添加完成后,可以预览当前布局,如图所示:

        可以看到,按钮已经显示出来了。接下来,要在活动中加载这个布局。

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

package com.example.activitytest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class FirstActivity extends AppCompatActivity {

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

        可以看到,调用了setContentView()方法给当前的活动加载一个布局,在setContentView()方法中,一般会出传入一个布局文件的id。在介绍项目资源时提到,项目中添加任何资源都会在R文件中生成一个相应的资源id,因此刚才创建的first_layout.xml布局的id现在应该是已经添加到R文件中了。在代码中引用布局文件,只需要调用R.layout.first_layout就可以得到first_layout.xml布局的id,然后将这个值传入setContentView()方法即可。

2.2.3 在AndroidManifest文件中注册

        所有的活动都要在AndroidManifest.xml中进行注册才能生效,而实际上FirstAcitivity已经在AndroidManifest.xml中注册过了,打开app/src/main/AndroidManifest.xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<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"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.ActivityTest">
        <activity
            android:name=".FirstActivity"
            android:exported="false" />
    </application>

</manifest>

        可以看到,活动的注册声明要放在<application>标签内,这里是通过<activity>标签来对活动进行注册的。在<activity>标签中使用了android:name指定具体注册哪一个活动,这里填入的.First-Activity是com.example.activitytest.FirstActivity的缩写。由于在最外层的<manifest>标签中已经通过package属性指定了程序的包名是com.example.activitytest,因此在注册活动时这一部分就可以省略。这里注意android:exported属性,该属性用来标示当前Activity是否可以被另一个Applica-tion的组件启动,true允许被启动,false禁止被启动。这里默认填入false,是因为该活动还未被配置为主活动,若建立时勾选创建主活动选择,则自动生成的代码中该属性会默认为true。这里要特别注意,如果该活动手动配置为主活动,但android:exported属性未更改为true,程序可能会报错崩溃。

        仅仅是这样注册了活动,程序仍然是不能运行的。因为还没有为程序配置主活动,当程序运行起来时,不知道首先要启动哪个活动。配置主活动的方法是在<activity>标签的内部加入<intent-filter>标签,并在这个标签里添加<action android:name="android.intent.action.MAIN"/><c-ategory android:name="android.intent.category.LAUNCHER"/>这两句声明即可。

        除此之外,可以使用android:label指定活动中标题栏的内容,标题栏是显示在活动最顶部的。需要注意的是,给主活动指定的label不仅会成为标题栏中的内容,还会成为启动器(Laun-cher)中应用程序显示的名称。修改后的AndroidManifest.xml文件,代码如下:

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

    <application
        ...>
        <activity
            android:name=".FirstActivity"
            android:exported="true"
            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>

        这样的话,FirstActivity就成为这个程序的主活动了。即点击桌面应用程序图标时首先打开的就是这个活动。另外需要注意,如果应用程序中没有声明任何一个活动作为主活动,这个程序仍然是可以正常安装的,只是无法在启动器中看到或打开这个程序。这种程序一般都是作为第三方服务提供其他应用在内部进行调用的,如支付宝快捷支付服务。

        运行程序,结果如下图:

        界面顶部是一个标题栏,里面显示刚才在注册活动时指定的内容。标题栏下面是在布局文件first_layout.xml中编写的界面,可以看到刚刚定义的按钮。

2.2.4 在活动中使用Toast

        Toast是Android系统提供的一种提醒方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息会在一段时间后自动消息,并且不会占用任何屏幕空间。

        首先需要定义一个弹出Toast的触发点,此处,让点击这个按钮的时候弹出一个Toast。在on-Create()方法中添加如下代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_layout);
        Button button1 = (Button) findViewById(R.id.button_1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(FirstActivity.this,"You clicked Button1",
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

        在活动中,通过findViewById()方法获取到在布局文件中定义的元素,传入R.id.button_1,得到按钮的实例。findViewById()方法返回的是一个View对象,需要向下转型将它转成Button对象。得到按钮的实例之后,通过调用setOnClickListener()方法为按钮注册一个监听器,点击按钮时会执行监听器中的onClik()方法。

        Toast的用法。通过静态方法makeText()创建出一个Toast对象,然后调用show()将Toast显示出来就可以了。需要注意,makeText()方法需要传入3个参数。第一个参数是Context,即Toast要求的上下文,由于活动本身就是一个Context对象,因此这里直接传入FirstActivity.this。第二个参数是Toast显示的文本内容第三个参数是Toast显示的时长,有两个内置常量可选择Toast.LENG-TH_SHORT和Toast.LENGTH_LONG。重新运行程序,点击按钮,可看到效果。

 2.2.5 在活动中使用Menu

        在res目录下新建一个menu文件夹,右击res目录----New----Directory,输入文件夹名menu,点击OK。接着在文件夹下再新建一个名叫main的菜单文件,右击menu文件夹----New----Menu resource file。点OK完成创建,在main.xml中添加如下代码:

<?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="Add"/>
    <item
        android:id="@+id/remove_item"
        android:title="Remove"/>
</menu>

        这里创建两个菜单项,其中<item>标签是用来创建具体的某一个菜单项,然后通过android:id给这个菜单项指定一个唯一的标识符,通过android:title给这个菜单项指定一个名称。

        接着重回到FirstActivity中重写onCreateOptionsMenu()方法,重写方法可用ctrl+O快捷键。

        在onCreateOptionsMenu()方法中编写如下代码:

 public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

        通过getMenuInflater()方法能够得到MenuInflter对象,再调用它的inflate()方法,就可以给当前活动创建菜单了。inflate()方法接收两个参数:第一个参数用于指定通过哪一个资源文件来创建菜单;第二个参数指定菜单项将添加到哪一个Menu对象当中,这里直接使用onCreateOptions-Menu()方法中传入的menu参数。最后这个方法返回true,表示允许创建的菜单显示出来,反之,返回false,则无法显示。

        定义菜单响应事件,在FirstActivity中重写onOptionsItemSelected()方法,如下所示:

 public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch(item.getItemId()){
            case R.id.add_item:
                Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show();
                break;
            case R.id.remove_item:
                Toast.makeText(this, "You clicked Remove", Toast.LENGTH_SHORT).show();
                break;
            default:
        }
        return true;
    }

        在onOptionsItemSelected()方法中,通过调用item.getItemId()来判断点击的是哪一个菜单项,然后给每个菜单项加入自己的逻辑处理。

        重新运行程序,会看到标题栏的右侧多了一个三点的符号,只有点击一下菜单按钮才会弹出里面的具体内容,不会占用任何活动的空间。如果你点击了Add菜单项就会弹出You clicked Add提示,点击Remove,同理。

2.2.6 销毁一个活动

        按一下Back键就可以销毁当前的Acitivity了。在程序中,Activity类提供了一个finish()方法,只需调用一下这个方法就可以通过代码销毁当前的Activity。修改按钮监听器中的代码,如下:

button1.setOnClickListener(new View.OnClickListener() {
            @Override
          public void onClick(View view) {
                finish(); 
            }
 });

        重新运行程序,这时点击一下按钮,当前的活动就被成功销毁了,效果和按下Back键是一样的。

2.3 使用Intent在活动之间穿梭

2.3.1 使用显式Intent

        在ActivtyTest项目中再快速创建一个Activity。这次命名为SecondActivity,并勾选Generate Layout File,给布局文件起名为second_layout,但不勾选Launcher Activity选项。不过自动生成的布局代码目前看有点复杂,这里还是使用比较熟悉的LinearLayout,编辑second_layout.xml,将里面的代码替换为如下内容:

<?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/button_2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 2"/>

</LinearLayout>

        Andoid Studio已经自动完成了该活动在AndroidMainfest.xml中的注册。由于SecondActivity不是主活动,因此不需要配置<intent-filter>标签里的内容。

        Intent是Android程序中各组件之间进行交互的一种重要方式,不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可用于启动活动、启动服务以及发送广播等场景。Intent大致分为两种:显式Intent和隐式Intent。

        Intent有多个构造函数的重载,其中一个是Intent(Context packageContext, Class<?>cls)。这个构造函数接收两个参数,第一个参数Context要求提供一个启动活动的上下文,第二个参数Class则是指定想要启动的目标活动,通过这个构造函数可以构建出Intent的“意图”。Activity类中提供了一个startActivity()方法,这个方法专门用于启动活动,它接收一个Intent参数,将构建好的Intent传入startActivity()方法就可以启动目标活动了。

        修改FirstActivity中按钮的点击事件,代码如下:

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
          public void onClick(View view) {
                Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });

        首先构建一个Intent传入FirstActivity.this作为上下文传入SecondActivity.class作为目标活动,意图即在FirstActivity这个活动的基础上打开SecondActivity这个活动。然后通过startActi-vity()方法执行这个Intent。重新运行程序,在FirstActivity界面点击一下按钮,会成功启动SecondActivity活动。按下Back键可以销毁当前活动,返回上一个活动。这种方式启动活动,称之为显式Intent

2.3.2 使用隐式Intent

        隐式Intent不明确指出想要启动哪一个活动,而是指定了一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并找出合适的活动去启动。

        通过在<activity>标签下配置<intent-filter>的内容,可以指定当前活动能够响应的action和category,打开AndroidManifest.xml,添加如下代码:

        <activity
            android:name=".SecondActivity"
            android:exported="false">
            <intent-filter>
                <action android:name="com.example.activitytest.ACTION_START"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

        在<action>标签中指明当前活动可以响应com.example.activitytest.ACTION_START这个action,而<category>标签包含了一些附加信息,更精确指明了当前活动能够响应的Intent中还可能带有的category。只有<action>和<category>中的内容同时能够匹配上Intent中指定的action和category时,这个活动才能响应该Intent。

        修改FirstActivity中按钮的点击事件,代码如下:

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.activitytest.ACTION_START");
                startActivity(intent);
            }
        });

        这里用了Intent的另一个构造函数,直接将action的字符串传了进去,表明想要启动能够响应com.example.activitytest.ACTION_START这个action的活动。android.intent.category.DEFAULT是一种默认的category,在调用startActivity()方法时会自动将这个category添加到Intent中。

        每个Intent中只能指定一个action,但却能指定多个category。修改FirstActivity中按钮的点击事件,代码如下:

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.activitytest.ACTION_START");
                intent.addCategory("com.example.activitytest.MY_CATEGORY");
                startActivity(intent);
            }
        });

        调用Intent中的addCategory()方法添加一个category,指定一个自定义的category。此时运行程序,点击按钮,程序会崩溃。因为没有活动可以响应这个Intent。在<intent-filter>标签中再添加一个category的声明,如下。再次运行程序,一切正常。

        <activity
            android:name=".SecondActivity"
            android:exported="false">
            <intent-filter>
                <action android:name="com.example.activitytest.ACTION_START"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="com.example.activitytest.MY_CATEGORY"/>
            </intent-filter>
        </activity>

  2.3.3 更多隐式Intent的用法

        隐式Intent不仅可以启动程序内的活动,还可以启动其他程序的活动,这可以用于Android多个应用程序之间功能共享。比如应用程序中需要展示一个网页,只需调用系统的浏览器来打开这个网页就行。修改FirstActivity中按钮点击事件的代码,如下:

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse("https://www.baidu.com"));
                startActivity(intent);
            }
        });

        首先指定Intent的action是Intent.ACTION_VIEW,这是一个Android系统内置的动作,其常量值为android.intent.action.VIEW。然后通过Uri.parse()方法,将一个网址字符串解析成一个Uri对象,再调用Intent的setData()方法将这个Uri对象传递进去。运行程序,点击按钮会打开系统浏览器。setData()方法接收一个Uri对象,主要用于指定当前Intent正在操作的数据,而这些数据通常都是以字符串的形式传入到Uri.parse()方法中解析产生的。

        与此对应,还可以在<inter-filter>标签中再配置一个<data>标签,用于更精确地指定当前活动能够响应什么类型的数据。<data>标签中主要可以配置以下内容:

  • android:scheme ----用于指定数据的协议部分,如上例中的http部分。
  • android:host -------用于指定数据的主机名部分,如上例中的www.baidu.com部分。
  • android:port -------用于指定数据的端口部分,一般紧随在主机名之后。
  • android:path -------用于指定主机名和端口之后的部分,如一段网址中跟在域名后的的内容
  • android:mimeType ----用于指定可以处理的数据处理,允许使用通配符的方式进行指定。

        只有<data>标签中指定的内容和Intent中携带的Data完全一致时,当前活动才能够响应该Intent。不过一般在<data>标签中都不会指定过多的内容,如上面浏览器示例中,其实只需要指定android:scheme为https,就可以响应所有的https协议的Intent。

        新建ThirdActivity,编辑布局文件third_layout.xml,同second_layout.xml。在AndroidMani-fest.xml中修改ThirdActivity的注册信息:

        <activity
            android:name=".ThirdActivity"
            android:exported="true">
            <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>

        在ThirdActivity的<intent-filter>中配置当前活动能够响应的action是Intent.ACTION_VIEW的常量值,category指定默认的category值,另外在<data>标签中通过android:scheme指定了数据的协议必须是https协议,这样ThirdActivity就和浏览器一样,能够响应一个打开网页的Intent了。另外,由于AndroidStudio认为所有能够响应ACTION_VIEW的Activity都应该加上BROWSABLE的catagory,否则就会给出一段告警提醒。加上BROWSABLE的catagory是为了实现deep link 功能,目前暂未涉及,所以这里直接在<intent-filter>标签上使用tools:ignore属性将警告忽略即可。运行程序,点击按钮,系统自动弹出一个列表,显示了目前能够响应这个Intent的所有程序。如果选择ActivityTest,则会启动ThirdActivity。

        除了https协议外,还可以指定很多其他协议,比如geo表示显示地理位置tel表示拨打电话。下面代码展示在程序中调用系统拨号界面。

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_DIAL);
                intent.setData(Uri.parse("tel:10086"));
                startActivity(intent);
            }
        });

        首先指定了Intent的action是Intent.ACTION.DIAL,这是一个Android系统的内置动作。然后再data部分指定了协议是tel,号码是10086。重新运行程序,点击按钮,显示拨号。

2.3.4 向下一个活动传递数据

        Intent可以在启动活动时传递数据。Intent中提供了一系列putExtra()方法的重载,可以把想要传递的数据暂存在Intent中,启动了另一个活动后,只需把这些数据再从Intent中取出就可以了。比如FirstActivity中有一个字符串,想把这个字符串传递到SecondActivity中,可以这样编写:

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
          public void onClick(View view) {
                String data = "Hello SecondActivity";
                Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
                intent.putExtra("extra_data", data);
                startActivity(intent);
            }
        });

        通过putExtra()方法传递一个字符串。注意这里putExtra()方法接收两个参数,第一个参数是键,用于后面从Intent中取值,第二个参数是真正要传递的数据。然后在SecondActivity中将传递的数据取出,并打印出来,代码如下:

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_activity);
        Intent intent = getIntent();
        String data = intent.getStringExtra("extra_data");
        Log.d("SecondActivity", data);
    }
}

        先通过getIntent()方法获取到用于启动SecondActivity的Intent,然后调用getStringExtra()方法,传入相应的键值,就可以得到传递的数据。如果传递的是整型数据,则使用getIntExtra()方法;如果传递的是布尔型数据,则使用getBooleanExtra()方法,以此类推。重新运行程序,点击按钮会跳转到SecondActivity,查看logcat打印信息,数据成功被打印。

2.3.5 返回数据给上一个活动

        Activity中有一个startActivityForResult()方法,用于启动活动,在活动销毁时能够返回一个结果给上一个活动。startActivityForResult()方法接收两个参数,第一个参数还是Intent,第二个参数是请求码,用于在之后的回调中判断数据的来源。该方法目前已被弃用,在此不再赘述。

        推荐使用registerForActivityResult()方法,该方法需要传入两个参数,第一个参数Activity-ResultContract,第二个回调参数ActivityResultCallback,返回一个ActivityResultLauncher对象。调用ActivityResultLauncher的launcher方法可以跳转到另一个Activity或发起权限请求。需要注意的是,registerForActivityResult()方法只能在onCreate()中注册。修改FirstActivity中代码,如下:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_layout);
        Button button1 =(Button)findViewById(R.id.button1);

        ActivityResultLauncher launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
                new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if(result.getResultCode() == RESULT_OK){
                    Log.d("FirstActivity", result.getData().getStringExtra("data_return"));
                }
            }
        });

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
          public void onClick(View view) {
                Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
                launcher.launch(intent);
            }
        });
    }

             这里调用registerForActivityResult()方法注册一个对Activity结果的监听。在SecondActivity被销毁后会回调上一个活动的onActivityResult()方法,因此需要这个方法来得到返回的数据。在点击事件中将intent传入launcher中。然后在SecondActivity中给按钮注册点击事件,并在点击事件中添加返回数据的逻辑,代码如下:

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_activity);
        Button button2 =(Button)findViewById(R.id.button_2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.putExtra("data_return", "Hello FirstActivity");
                setResult(RESULT_OK,intent);
                finish();
            }
        });
    }
}

        构建一个Intent用于传递数据,把传递的数据存放在Intent中,然后调用setResult()方法。该方法用于向上一个活动返回数据。setResult()方法接收两个参数,第一个参数用于向上一个活动返回处理结果,一般只用RESULT_OK或RESULT_CANCELED这两个值,第二个参数把带有数据的Intent传递回去,然后调用finish()方法销毁当前活动。重新运行程序,在FirstActivity界面点击按钮会打开SecondActivity,然后点击Button2按钮会回到FirstActivity,这是查看打印信息,可成功看到返回数据。

        如果是通过按下Back键回到FirstActivity,可以在SecondActivity中重写onBackPressed()方法来解决,代码如下:

    @Override
    public void onBackPressed() {
        Intent intent = new Intent();
        intent.putExtra("data_return", "Hello FirstActivity");
        setResult(RESULT_OK, intent);
        finish();
    }
  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值