继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

❤️【Android精进之路-05】怎么创建Activity,如何启动另一个Activity,干货满满,建议收藏❤️

码农飞哥
关注TA
已关注
手记 14
粉丝 0
获赞 3

您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦。
本文亮点:详细介绍Activity的创建以及如何传递参数和接收返回参数

Android系列文章都在Android专栏中,欢迎小伙伴关注。

源码地址

前言

上一篇文章[❤️【Android精进之路-04】Android核心组件Activity,必须掌握的知识点(Activity是什么,生命周期是怎样的)❤️]介绍了Activity的基本概念以及生命周期,但是没有说到如何创建Activity,Activity之间如何传值。SO,本文将重点讲解Activity的创建以及如何Activity之间如何传递参数。
源代码地址:https://gitee.com/jayxiang31/android-studio-projects.git
https://gitee.com/jayxiang31/android-studio-projects.git

创建一个自定义的Activity

利用Android Studio可以直接创建一个自定义的Activity,创建的方式是:

  1. 如下图1所示,在java源代码的包路径下右键选中New->Activity 。Activity选择项下有各种各样的Activity。我们可以按照需选中其中一个Activity进行创建。这里我选中Empty Activity 选项。
    图1
  2. 图2中指定Activity的名称和布局页面的名称之后,点击Finish就可以创建一个自定义的Activity。
    图2
    这里使用Android Studio的好处就是他可以帮助我们自动创建布局页面activity_test.xml 以及将Activity注册到AndroidManifest.xml中
  3. 布局页面 **layout->activity_test.xml **
<?xml version="1.0" encoding="utf-8"?>
<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=".TestActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
  1. 在AndroidManifest.xml 中注册Activity
<manifest ... >
    <application ... >
        <activity android:name = ".TestActivity" />
        ...
    </application ... >
    ...
</manifest >

如果Activity是主Activity的话则其注册会多两行配置。

<manifest ... >
    <application ... >
       <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/title_activity_main"
            android:theme="@style/Theme.Activity_test.NoActionBar">
            <intent-filter>
                <!-- 表示该Activity作为主Activity出现 -->
                <action android:name="android.intent.action.MAIN" />
                <!-- 表示该Activity会被显示在最上层的启动列表中 -->
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        ...
    </application ... >
    ...
</manifest >

<action android:name="android.intent.action.MAIN" /> 表示该Activity作为主Activity出现。
<category android:name="android.intent.category.LAUNCHER" />表示该Activity会被显示在最上层的启动列表中。

Activity绑定自定义视图(布局页面)

说完了如何创建自定义Activity之后,接下来让我们来看一下Activity如何绑定自定义视图。重写onCreate方法,在该方法中通过setContentView方法来设置需要绑定的视图。这里新建了一个名为my_layout.xml的视图。然后通过 R.layout.my_layout 来获取它。这里的R类是基于外部资源生成的类,在编译项目时被创建,其包含了所有的 rest/目录下的资源ID,如果布局文件,资源文件,图片。res目录下保存的文件大多数都会被编译,并且被赋予资源ID,这些ID被保存在R.java文件中,这样我们就可以在程序中通过ID来访问res类的资源。

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

启动另一个Activity

Android应用程序中除了主Activity由应用程序启动以外,其他的Activity都是由用户操作启动。所以如何启动另一个Activity。启动Activity的方法是:startActivity(new Intent(MainActivity.this, AnotherAty.class)); 这个方法一般是放在一个按钮的监听事件中调用。

  1. 这里在主Activity的视图my_layout.xml中添加了一个按钮用于启动另一个Activity。
  <Button
        android:id="@+id/btnStartAnotherAty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="启动另一个Activity"
        tools:layout_editor_absoluteX="116dp"
        tools:layout_editor_absoluteY="257dp"
        tools:ignore="MissingConstraints" />

这里定义了一个名为btnStartAnotherAty的Button按钮。用于用户点击时启动另一个Activity。
3. 在MainActivity中给按钮添加点击监听事件启动AnotherAty。

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_layout);
        findViewById(R.id.btnStartAnotherAty).setOnClickListener(view -> {
            //启动目标Activity
            startActivity(new Intent(MainActivity.this, AnotherAty.class));
        });
    }

这里findViewById(R.id.btnStartAnotherAty) 方法非常重要,他表示根据ID找到名为btnStartAnotherAty按钮,接着调用setOnClickListener 方法绑定一个按钮点击的监听事件,下面介绍的Activity之间传值也是要写在该事件里。
如果想从Activity跳转到一个网页的话也是可以的,只需要像下面这样就可以实现:

  startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse("https://feige.blog.csdn.net/")));

上面的代码演示了从当前Activity跳转到[码农飞哥]这个页面中。
运行结果是:
在这里插入图片描述

关闭Activity

关闭Activity用finish()方法,关闭之前启动的其他Activity可以用finishActivity() 方法。
虽然Android系统提供了finish()方法关闭Activity,但是不建议开发人员调用这个方法强制关闭Activity。因为Android系统维护了Activity完整的生命周期。并且提供了完备的资源回收机制和资源重建机制,可以动态地回收和重建 Activity。

Activity传递数据

Activity传递数据本质上还是向Intent中存放数据。有三种不同的方式:
第一种方式是直接将数据设置到Intent中,

intent.putExtra("name", "码农飞哥,你好");

第二种方式是向Intent中设置一个值对象,

intent.putExtra("user", new User("码农飞哥", 30));

第三种方式是向Intent中设置一个Bundle对象。

   Bundle bundle = new Bundle();
   bundle.putString("name", "码农飞哥,Bundle");
   bundle.putInt("age", 30);
   intent.putExtras(bundle);

下面就详细看一下吧!

Activity之间传递简单数据

传递简单数据可以直接向Intent中设值,一般而言只需要传递少量的基本类型的数据可以直接通过intent的putExtra方法进行设置传值。
在这里插入图片描述

  1. 源Activity的传值操作
 Intent intent = new Intent(MainActivity.this, TheAty.class);
 //1.传简单数据
 intent.putExtra("name", "码农飞哥,你好");
 startActivity(intent);

这里传递了一个名为name的String的数据。
2. 被启动目标Activity接收值的操作

 Intent intent = getIntent();
 intent.getStringExtra("name")

这里接收值调用的方法根据值的类型不同,需要调用不同的方法,即如果传入的值是String类型在调用getStringExtra类型,如果是int类型则调用getIntExtra方法。
在这里插入图片描述
运行结果是:

Activity之间传递值对象

当传入的数据比较多,类型比较复杂时,则不太适合直接使用intent直接设置传递了。这是可以将需要传递的值封装到一个对象Bean中。比如下面定义了一个User对象,该对象里面有name和age两个属性。这里需要注意的是传递的值对象必须要实现java.io.Serializable接口使之可以被序列化。否则,该对象不能被设值到intent中

public class User implements Serializable {

    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
 	······省略get,set方法······
}

如果是使用Serializable接口进行序列化的话,也可以使用Android系统提供的Parcelable接口来实现序列化,这个接口相较于Serializable接口性能更好。

public class User2 implements Parcelable {

    private String name;
    private int age;


    protected User2(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<User2> CREATOR = new Creator<User2>() {
        @Override
        public User2 createFromParcel(Parcel in) {
            return new User2(in);
        }

        @Override
        public User2[] newArray(int size) {
            return new User2[size];
        }
    };
}
  1. 源Activity的传值操作
 Intent intent = new Intent(MainActivity.this, TheAty.class);
//2. 传递值对象
 intent.putExtra("user", new User("码农飞哥", 30));
 startActivity(intent);
  1. 被启动目标Activity接收值的操作
 Intent intent = getIntent();
 User user = (User) intent.getSerializableExtra("user");

如果使用的是Serializable序列话的话,则调用getSerializableExtra方法。如果是Parcelable序列化的话,则调用getParcelableExtra方法。

Activity之间传递数据包Bundle

第三种传值的方式就是传递数据包Bundle。Bundle数据包设置方式类似于Map也是传入键值对,不同数据类型需要调用不同的put方法

  1. 源Activity的传值操作
    Intent intent = new Intent(MainActivity.this, TheAty.class);
    Bundle bundle = new Bundle();
    bundle.putString("name", "码农飞哥,Bundle");
    bundle.putInt("age", 30);
    intent.putExtras(bundle);
    startActivity(intent);

这里调用putExtras方法将Bundle对象放入Intent中。当然也可以调用putExtra方法设置Bundle对象。使用putExtra的方式是:intent.putExtra("data",bundle) 需要指定一个键。
2. 被启动目标Activity接收值的操作

Intent intent = getIntent();
Bundle data = intent.getExtras();
String.format("name=%s,age=%s,name1=%s", data.getString("name"), data.getInt("age"), data.getString("name1", "不存在的默认值"))

如果设值使用的是putExtras方法,那么在取值时则需要使用getExtras()方法。如果设值使用的intent.putExtra("data",bundle) ,则取值需要使用intent.getExtra("data")
另外,从Bundle中取值是也是根据数据类型的不同调用不同的方法,String类型则调用getString(),int类型则调用getInt()方法。如果张冠李戴的话则获取不到指定的值。如果指定name对应的值不存在,可以设置默认值,就是上面data.getString("name1", "不存在的默认值") 这样,名为name1的值不存在时,则显示设置的默认值不存在的默认值

运行结果

请添加图片描述

获取被启动Activity的返回结果

前面介绍的都是源Activity向目标Activity传递数据,那么源Activity怎么接收被启动Activity的返回结果呢?这里也是可以实现的。

  1. 源Activity的操作
    1. 在源Activity的视图中定义一个TextView用于接收返回的结果
  <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="呈现结果" />
  1. 在源Activity的onCreate方法中实例化TextView,实现按钮的点击监听事件。这里需要特别注意是不能在调用startActivity启动目标Activity。而需要调用startActivityForResult启动目标Activity。这个方法有一个名为requestCode的参数用于指定请求的code。这里指定requestCode为0。
 private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //定义一个textView接收返回的值
        textView = findViewById(R.id.textView);
        findViewById(R.id.btnStartAty).setOnClickListener(view -> {
            Intent intent = new Intent(MainActivity.this, TheAty.class);
            startActivityForResult(intent, 0);
        });
    }
  1. 接着需要重写onActivityResult方法给TextView对象赋值。
   @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        textView.setText("另一个Activity返回的数据是:" + data.getStringExtra("data"));
    }
  1. 被启动目标Activity的操作,这里的操作主要就是设置返回值
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_the_aty);
        editText = findViewById(R.id.editText);
        //定义一个名为sendBackDataBtn的按钮用于跳回源Activity。
        findViewById(R.id.sendBackDataBtn).setOnClickListener(view -> {
            Intent resultIntent = new Intent();
            resultIntent.putExtra("data", editText.getText().toString());
            setResult(1, resultIntent);
            //结束当前的Activity
            finish();
        });
    }

运行结果:
请添加图片描述

总结

本文详细介绍了Activity的创建以及传值操作,希望对读者朋友们有所帮助。

全网同名【码农飞哥】。不积跬步,无以至千里,享受分享的快乐
我是码农飞哥,再次感谢您读完本文

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP