1、我们还是先来实践一下,从一个Activity跳转到另一个Activity吧。我们创建一个空Activity的程序,然后新建了一个Activity(Activity本质上是一个java类,只不过它继承了不同的Activity类而已,我们完全可以通过创建普通java类然后继承我们想继承的Activity类,但是我们直接创建Activity的好处就是它会帮我们自动生成一些函数,比如这里的onCreate函数)。
2、我们可以看到创建好AnotherAty之后,它还帮我们自动创建了一个布局文件叫activity_another_aty.xml
,并且在AnotherAty里面自动帮我们默认加载这个布局文件。
3、我们在MainActivity里面添加一个按钮,其实并不是在MainActivity里面添加,而是在它的布局文件里添加,也就是说在activity_main.xml
里添加,由于我们默认的是相对布局,所以这个距离还是需要我们调整一下,不然就把上面文字遮住了:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
……
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转到另一个Aty"
android:layout_marginTop="30dp"
android:id="@+id/btnStartAnotherAty"/>
</RelativeLayout>
4、接下来就是实现功能了,回到MainActivity里面。这里的核心就是通过id找到那个按钮,然后给这个按钮添加一个点击事件监听,如果点击的话,就打开一个Activity,这里用的是startActivity函数,这个函数里面需要的Intent参数,这个后续详细说明,这里不表。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnStartAnotherAty).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,AnotherAty.class));
}
});
}
}
5、从这个简单的程序可以看出来,Activity像是iOS里的控制器,布局像是iOS里的视图。安卓开发这里,我们可以在布局文件里尽情添加控件,但是需要逻辑判断和操作的东西我们都是在Activity里面写的代码,如果需要使用到控件了,在Activity里面用findViewById函数可以找到那个控件(前提是给这个控件得添加id这个属性并赋值)。
6、我们刚刚说,MainActivity里面有个onCreate函数,其实这只是Activity生命周期里的一个环节。总结起来一个Activity的生命周期是创建onCreate(),对应的就是摧毁onDestroy()。但是每次创建很耗资源的好不好,所以在不被摧毁的情况下,可以通过开启onStart()、onRestart()和停止onStop()来使用这个Activity。又但是每次开启或者重启也是很好资源的,所以在没有被停止的情况下,我们用恢复onResume()和暂停onPause()来使用Activity。看出来了么?其实这三组是逐层嵌套的,目的就是根据目前Activity的状态来选择资源消耗最少的方式使用,比如这个Activity已经被摧毁了,那没办法了,只能通过创建然后乖乖的一层层开启恢复来使用,但是如果这个Activity没有被摧毁只是不可见了,那么可以通过开启后乖乖的再通过恢复来使用,如果这个Activity只是被另一个Activity“抢镜了”自己被搁置在后面后场的话,那要使用就之用通过恢复即可。具体可以看帮助文档里官方这张生命周期图,很详细。
7、 至于2个Activity切换的时候函数的调用顺序,这个自己写一个打印程序就能测试到。假设从A切换到B,一般的顺序是A的onPause()->B的onCreate()->B的onStart()->B的onResume()->A的onStop(),要是再回到A的话,就直接执行A的onRestart()->A的onStart()。为什么说这是一般顺序,因为还有特殊情况,比如B是一个对话框,这个时候其实B出来的时候A还是看的见的,所以顺序就是A的onPause()->B的onCreate()->B的onStart()->B的onResume(),然后关闭B对话框时,执行的是A的onResume(),以及后面B的onPause()->B的onStop()->B的onDestroy()。
8、利用Intent传值(传简单的数据),主要是利用Intent的putExtra()函数来绑定数据。
在MainActivity里:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnStartAnotherAty).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this,AnotherAty.class);
i.putExtra("name","Eric");//绑定数据
startActivity(i);
}
});
}
}
在AnotherAty里:
public class AnotherAty extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another_aty);
Intent i = getIntent();//获取和这个Activity相关的Intent
tv = (TextView) findViewById(R.id.tv);
tv.setText(i.getStringExtra("name"));//利用Intent的getxxxExtra()函数获取数据
}
}
9、利用Bundle传递复杂的数据,也就是说把数据放在Bundle里面,然后把Bundle给Intent,获取的时候是从Intent先获取Bundle,然后从Bundle里面取出数据。
在MainActivity里:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnStartAnotherAty).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this,AnotherAty.class);
Bundle b = new Bundle();
b.putString("name","Eric");
b.putInt("age",30);
// 第一种方式
i.putExtras(b);
// 第二种方式
// i.putExtra("data",b);
startActivity(i);
}
});
}
}
在AnotherAty里:
public class AnotherAty extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another_aty);
Intent i = getIntent();
// 第一种获得bundle
Bundle b = i.getExtras();
// 第二种获得bundle
// Bundle b = i.getBundleExtra("data");
tv = (TextView) findViewById(R.id.tv);
tv.setText(String.format("name:%s,age:%d",b.getString("name"),b.getInt("age")));
}
}
10、8和9传递的都是一些简单的数据或者通过bundle添加了多个同类型的数据,但是实际开发中我们经常传递的是值对象,比如User类,我们其实一样可以通过Intent绑定这个数据,但是需要这个值对象实现Serializable或者Parcelable。通过实现Serializable比较简单,直接添加实现这个类即可,里面的序列化操作系统会帮我们自己动完成,如下面:
我们的Fuser对象:
package club.finnovate.androidactivity;
import java.io.Serializable;
/**
* Created by Andy on 2016/12/29.
*/
// 实现Serializable接口即可
public class Fuser implements Serializable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Fuser(String name,int age){
this.name=name;
this.age=age;
}
}
在MainActivity里:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnStartAnotherAty).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this,AnotherAty.class);
i.putExtra("fuser",new Fuser("Eric",28));//通过构造函数创建
startActivity(i);
}
});
}
}
在AnotherAty里:
public class AnotherAty extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another_aty);
Intent i = getIntent();
// 还是从Intent里获取,只不过是利用getSerializableExtra()函数
Fuser fuser = (Fuser) i.getSerializableExtra("fuser");
tv = (TextView) findViewById(R.id.tv);
tv.setText(String.format("name:%s,age:%d",fuser.getName(),fuser.getAge()));
}
}
11、上面利用Serializable简单是简单,但是效率低。所以出现了Parcelable,你可能会猜到,这家伙虽然效率高了,但是操作是复杂了一些。
在Fuser对象里:
package club.finnovate.androidactivity;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by Andy on 2016/12/29.
*/
// 实现可Parcelable接口并实现里面的2个函数和1个创建
public class Fuser implements Parcelable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Fuser(String name,int age){
this.name=name;
this.age=age;
}
// 第一个函数,不管
@Override
public int describeContents() {
return 0;
}
// 第二个函数,使用writexxx()函数。如果有多个String或者Int的话用writeBundle()函数
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(getName());
dest.writeInt(getAge());
}
// 1个创建
public static final Creator<Fuser> CREATOR = new Creator<Fuser>() {
@Override
public Fuser createFromParcel(Parcel source) {
return new Fuser(source.readString(),source.readInt());
}
@Override
public Fuser[] newArray(int size) {
return new Fuser[size];
}
};
}
在AnotherAty里:
public class AnotherAty extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another_aty);
Intent i = getIntent();
// 不需要强制类型转换
Fuser fuser = i.getParcelableExtra("fuser");
tv = (TextView) findViewById(R.id.tv);
tv.setText(String.format("name:%s,age:%d",fuser.getName(),fuser.getAge()));
}
}
12、Activity的反向传值,也就是通过A跳转到B,再回到A的时候把B里面需要的值反向传递给A供A使用。
在MainActivity里:
public class MainActivity extends AppCompatActivity {
private TextView tv_main;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_main = (TextView) findViewById(R.id.tv_main);
findViewById(R.id.btnStartAnotherAty).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this,AnotherAty.class);
// 第二个参数是requestCode,用来标示是哪个按钮或者控件跳转到其他页面的,这个requestCode在下面的函数里是可以获取的,也就是说它还是会回来的
startActivityForResult(i,0);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
tv_main.setText(data.getStringExtra("name"));
}
}
在AnotherAty里:
public class AnotherAty extends AppCompatActivity {
private EditText et_another;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another_aty);
et_another = (EditText) findViewById(R.id.et_another);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent();
i.putExtra("name",et_another.getText().toString());
// 第二个就是返回的数据,还是通过Intent载体传递,第一个是resultCode,用来标示结果状态
setResult(RESULT_OK,i);
// 关闭当前Aty
finish();
}
});
}
}