您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦。
本文亮点:详细介绍Activity的创建以及如何传递参数和接收返回参数
Android系列文章都在Android专栏中,欢迎小伙伴关注。
源码地址
https://gitee.com/jayxiang31/android-studio-projects/tree/master/activity_test
https://gitee.com/jayxiang31/android-studio-projects/tree/master/Android_Activity
前言
上一篇文章[❤️【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所示,在java源代码的包路径下右键选中New->Activity 。Activity选择项下有各种各样的Activity。我们可以按照需选中其中一个Activity进行创建。这里我选中Empty Activity 选项。
- 图2中指定Activity的名称和布局页面的名称之后,点击Finish就可以创建一个自定义的Activity。
这里使用Android Studio的好处就是他可以帮助我们自动创建布局页面activity_test.xml 以及将Activity注册到AndroidManifest.xml中 - 布局页面 **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>
- 在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));
这个方法一般是放在一个按钮的监听事件中调用。
- 这里在主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方法进行设置传值。
- 源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];
}
};
}
- 源Activity的传值操作
Intent intent = new Intent(MainActivity.this, TheAty.class);
//2. 传递值对象
intent.putExtra("user", new User("码农飞哥", 30));
startActivity(intent);
- 被启动目标Activity接收值的操作
Intent intent = getIntent();
User user = (User) intent.getSerializableExtra("user");
如果使用的是Serializable序列话的话,则调用getSerializableExtra方法。如果是Parcelable序列化的话,则调用getParcelableExtra方法。
Activity之间传递数据包Bundle
第三种传值的方式就是传递数据包Bundle。Bundle数据包设置方式类似于Map也是传入键值对,不同数据类型需要调用不同的put方法
- 源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的返回结果呢?这里也是可以实现的。
- 源Activity的操作
- 在源Activity的视图中定义一个TextView用于接收返回的结果
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="呈现结果" />
- 在源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);
});
}
- 接着需要重写onActivityResult方法给TextView对象赋值。
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
textView.setText("另一个Activity返回的数据是:" + data.getStringExtra("data"));
}
- 被启动目标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的创建以及传值操作,希望对读者朋友们有所帮助。
全网同名【码农飞哥】。不积跬步,无以至千里,享受分享的快乐
我是码农飞哥,再次感谢您读完本文。