活动
活动基本用法
1.Menu
-
创建menu 包->创建menu.xml,添加item
-
回到活动中重写onCreateOptionsMenu()和onOptionsItemSelected()
//显示菜单
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;//允许菜单显示
}
//菜单相应事件
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.menu1_1:
Toast.makeText(MainActivity.this, "点击第1-1个菜单!", Toast.LENGTH_SHORT).show();
break;
case R.id.menu1_2:
Toast.makeText(MainActivity.this, "点击第1-2个菜单!", Toast.LENGTH_SHORT).show();
break;
case R.id.menu2:
Toast.makeText(MainActivity.this, "点击第二个菜单!", Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}
使用Intent进行活动穿梭
1.Intent四大属性
- Action属性的值是一个字符串,它代表了系统中定义的一系列常用动作。通过**setAction()**方法或在清单文件AndroidMainfest.xml中设置。默认为:DEFAULT。
- Data通常是URL格式定义的操作数据。列如:tel//。通过**setData()**方法设置。
- Category属性用于指定当前动作(Action)被执行的环境。通过**addCategory()**方法或在清单文件 AndroidMainfest.xml中设置.默认为:CATEGORY_DEFAULT。
- Extras主要用于传递目标组件所需要的额外数据。通过**putExtras()**方法设置.
2.显式Intent和隐式Intent
显式Intent主要用于程序内的活动穿梭
隐式Intent主要用户程序间的活动穿梭,使用隐式Intent,要知道对面的action和category,一个intent只能指定一个action,但能指定多个category
3.数据传递
传递对象
步骤一,创建实体类并实现Parcelable或者Serialization接口
//方法一:Parcelable
public class Person implements Parcelable{
String name;
int age;
public PersonParcelable(){}//这个要自己写
public PersonParcelable(Parcel in) {
name = in.readString();
age = in.readInt();
}
public static final Creator<PersonParcelable> CREATOR = new Creator<PersonParcelable>() {
@Override
public PersonParcelable createFromParcel(Parcel in) {
return new PersonParcelable(in);
}
@Override
public PersonParcelable[] newArray(int size) {
return new PersonParcelable[size];
}
};
//getter and setter...
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(name);
parcel.writeInt(age);
}
}
//方法二:Serialization
public class Person implements Serializable {
private String name;
private int age;
//getter and setter...
}
步骤二,使用intent.putExtra(String name, Object object),将数据放入intent
public class MainActivity extends AppCompatActivity {
//...
public void dataTrans(View view) {
Intent intent = new Intent(MainActivity.this, DataTransActivity.class);
Person person = new PersonParcelable();
person.setName("yxq dataTrans");
person.setAge(18);
intent.putExtra("person", person);
startActivity(intent);
}
}
步骤三,在接收活动中接收intent
public class DataTransActivity extends AppCompatActivity {
//...
public void initView() {
TextView name = this.findViewById(R.id.name);
TextView age = this.findViewById(R.id.age);
Intent intent = getIntent();
//方式一
PersonParcelable person = intent.getParcelableExtra("person");
//方式二
PersonSerializable person = (PersonSerializable) intent.getSerializableExtra("person");
name.setText(person.getName());
age.setText(person.getAge()+"");
}
}
数据返回
步骤一,在第一个活动中使用startActivityForResult(intent, requestCode)表示开启下一个活动并请求数据返回
步骤二,在下一个活动中,使用setResult(resultCode, intent)表示设置返回数据内容
步骤三,在第一个活动中重写onActivityResult(),根据requestCode判断请求的是哪一个活动,根据resultCode判断返回的结果**
public class MainActivity extends AppCompatActivity {
public void toNextPageForResult(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivityForResult(intent, 619);//这里的619是请求码,就是下面的requestCode
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 619:
if (resultCode == RESULT_OK) {
Toast.makeText(this, "成功!", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "取消!", Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
}
public class SecondActivity extends AppCompatActivity {
//...
public void initEvent() {
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
//intent.putExtra();
setResult(RESULT_OK, intent);//一般就使用RESULT_OK和RESULT_CANCELED这两个值
finish();
}
});
}
}
活动生命周期
FirstActivity打开SecondActivity:
1.FirstActivity第一次被创建时会依次执行onCreate()、onStart()、onResume()
2.从FirstActivity中启动SecondActivity
3.如果SecondActivity完全把FirstActivity遮住
- FirstActivity就会依次执行onPause()和onStop(),SecondActivity如果第一次创建就会依次执行onCreate()、onStart()、onResume(),如果已经被创建,就会先执行onRestart(),之后依次执行onStart()和onResume()
- 从SecondActivity返回FirstActivity,FirstActivity就会执行onRestart(),之后依次执行onStart()和onResume();SecondActivity就会依次执行onPause(),onStop()和onDestory()
- 先执行onPause(),再执行另一个活动的生命周期方法
4.如果SecondActivity没有完全把FirstActivity遮住
- FirstActivity就只会执行onPause(),SecondActivity如果第一次创建就会依次执行onCreate()、onStart()、onResume(),
- 从SecondActivity返回FirstActivity,FirstActivity就只会执行onResume();SecondActivity就会依次执行onPause(),onStop()和onDestory()
- 先执行onPause(),再执行另一个活动的生命周期方法
活动的启动模式
1.standard
默认启动模式,每次启动都会创建一个新的实例,不在是否已在返回栈中
2.singleTop
若栈顶已经是该活动,则认为可以直接使用而不用创建新的实例
3.singleTask
启动时会检查栈中是否包含该活动,若有则将该活动之上的活动统统出栈
4.singleInstance
启用新的返回栈来管理这个活动
活动的最佳实践
1.Activity被回收了怎么办 重写onSaveInstanceState()
2.知晓当前活动是哪一个活动 BaseActivity
public abstract class BaseActivity extends AppCompatActivity {
private static final String TAG = "BaseActivity";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, getClass().getSimpleName());//知晓当前是哪一个活动实例
ActivityManager.addActivity(this);
setContentView(getView());
initView();
initEvent();
}
public abstract int getView();
public void initView() {}
public void initEvent() {}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityManager.removeActivity(this);
}
}
3.随时随地退出程序 ActivityManager
public class ActivityManager {
public static List<Activity> sActivities = new ArrayList<>();
public static void addActivity(Activity activity){
sActivities.add(activity);
}
public static void removeActivity(Activity activity){
sActivities.remove(activity);
}
public static void finishAll(){
for (Activity activity : sActivities) {
if (!activity.isFinishing()) {
activity.finish();
}
}
sActivities.clear();
}
}
4.启动活动的最佳写法:调用被启动活动中的静态方法,调用后便知道传递的数据
//FirstActivity
public void toSecondPager(View view) {
//显式跳转
//Intent intent = new Intent(MainActivity.this, SecondActivity.class);
//startActivityForResult(intent, 1);
SecondActivity.actionStart(MainActivity.this, "yxq", "yxqq");
}
//SecondActivity
public static void actionStart(Context context, String data1, String data2){
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra("param1", data1);
intent.putExtra("param2", data2);
context.startActivity(intent);
}