四大组件之一的Activity组件,在应用中的一个Activity可以用来表示一个界面,意思可以理解为“活动”,即一个活动开始,代表Activity组件启动,活动结束,代表一个Activity的生命周期结束。一个Android应用必须通过Activity来运行和启动,Activity的生命周期交给系统统一管理。
在Android中,activity拥有三个基本状态:
Resumed 一个新Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。
Paused 当Activity被另一个透明或者Dialog样式的Activity覆盖时的状态。此时它依旧与窗口管理器保持连接,系统继续维护其内部状态,所以它依然可见,但它己经失去了焦点故不可与用户交互。
Stopped 当Activity被另一个Activity覆盖、失去焦点并不可见时处于Stopped状态
七大方法:
在Android中,不同的Activity 实例可能运行在一个进程中, 也可能运行在不同的进程中。因此我们需要一种特别的机制帮助我们在Activity之间传递消息。Android 中通过Intent对象来表示一条消息,一个Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比- -封Email,其中不仅应该包含收件地址,还可以包含具体的内容。对于一个Intent对象,消息“目的地是必须的,而内容则是可选项。
两种方式
主界面视图
Activity1中数据传递的方法
public class MainActivity extends AppCompatActivity {
private EditText editText_info;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText_info=findViewById(R.id.editText_info);
}
/*
*启动Activity2,并且传递信息
* intent(意图)
* */
public void sendclick(View view){
//创建一个意图(想干什么)参数(上下文、要跳转的组件的字节码)
Intent intent=new Intent(this,Main2Activity.class);
String info=editText_info.getText().toString();
//封装要传递的数据
Bundle data=new Bundle();
data.putString("info",info);
intent.putExtra("data",data);
startActivity(intent);
}
}
数据接收的界面布局
Activity2接受数据
public class Main2Activity extends AppCompatActivity {
private TextView textView_info;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
textView_info=findViewById(R.id.info);
Intent intent=getIntent();
Bundle data=intent.getBundleExtra("data");
String info=data.getString("info");
textView_info.setText(info);
}
}
只需替换两端部分的代码即可
数据发送页面
Bundle data=new Bundle();
data.putString("info",info);
intent.putExtra("data",data);
替换为
intent.putExtra("info",info);
数据接收页面
Bundle data=intent.getBundleExtra("data");
String info=data.getString("info");
替换为
String info=intent.getStringExtra("info");
创建一个自定义类
package com.example.myapplication5;
import java.io.Serializable;
public class Cat implements Serializable {
String name;
int age;
String activity;
@Override
public String toString() {
return "Cat{"+"name='"+name+"\'"+",age="+age+",activity='"+activity+"\'"+"}";
}
}
传递数据方创建按钮的单击事件方法
public void sendObjClick(View v){
Cat cat=new Cat();
cat.name="汤姆";
cat.age=2;
cat.activity="抓杰瑞";
Intent intent=new Intent(this,Main2Activity.class);
intent.putExtra("cat",cat);
startActivity(intent);
}
接收数据
Cat cat= (Cat) intent.getSerializableExtra("cat");
textView_info.setText(cat.toString());
第二种方法:Parcelable方法(这种方式性能更好,官方更推荐)
创建对象类
package com.example.myapplication5;
import android.os.Parcel;
import android.os.Parcelable;
public class Dog implements Parcelable {
String type;
int age;
String job;
//对象的创建器还原写入的数据
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public Dog createFromParcel(Parcel in) {
Dog dog=new Dog();
dog.type = in.readString();
dog.age = in.readInt();
dog.job = in.readString();
return dog;
}
@Override
public Dog[] newArray(int size) {
return new Dog[size];
}
};
@Override
public String toString() {
return "Dog{"+"种类='"+type+"\'"+",年龄="+age+",工作='"+job+"\'"+"}";
}
@Override
public int describeContents() {
return 0;
}
//写入数据
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(type);
dest.writeInt(age);
dest.writeString(job);
}
}
按钮单击事件方法
public void sendObj2Click(View v){
Dog dog=new Dog();
dog.type="二哈";
dog.age=1;
dog.job="拆迁队";
Intent intent=new Intent(this,Main2Activity.class);
intent.putExtra("dog",dog);
startActivity(intent);
}
数据接收
Dog dog=intent.getParcelableExtra("dog");
textView_info.setText(dog.toString());
Android提供了一个机制,跳转到其他activity时,再返回,可以接受到其他activity返回的值,无需再start新的当前activity;下面的示例中,创建两个Activity,其中在MyActivity2中输入用户名和电话号码,然后单击"下一步“启动MyActivity3,在MyActivity3中把用户名和电话号码显示在TextView中,然后当单击该Activity的“上一步”按钮时,把之前传过来的数据原样返回给上一个Activity。
做一个打电话的示例:
主界面的布局
package com.example.myapplication5;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
public class MainActivityResult extends AppCompatActivity {
private EditText editText_number;
private static final int REQUESTCODE_1=0x1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
editText_number=findViewById(R.id.editText_number);
}
//选择一个电话号码
public void selectClick(View v){
Intent intent = new Intent(this, PhoneNumberListActivity.class);
//intent、请求编码
startActivityForResult(intent,REQUESTCODE_1);
}
//重写该方法处理返回结果
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==REQUESTCODE_1&&resultCode==RESULT_OK){
String number=data.getStringExtra("number");
editText_number.setText(number);
}
}
//拨打电话
public void callClick(View v){
String number =editText_number.getText().toString();
Intent intent=new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+number));
startActivity(intent);
}
}
创建一个listview,存号码
在PhoneNumberListActivity创建方法
package com.example.myapplication5;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class PhoneNumberListActivity extends AppCompatActivity {
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
listView=findViewById(R.id.listView);
final String[] numbers={"17474749174","13838389438","18989897789","13232329527","13548694869"};
ArrayAdapter adapter =new ArrayAdapter(
this,android.R.layout.simple_list_item_1,android.R.id.text1,numbers);
listView.setAdapter(adapter);
//选项单击事件
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
String number=numbers[position];
//getIntent();
Intent intent=new Intent();
intent.putExtra("number",number);
setResult(RESULT_OK,intent);//设置返回结果
finish();//结束当前的界面
}
});
}
}
点击select选择号码并传回主页面,在文本框中显示
在清单文件中加入打电话的权限,就可以模拟打电话功能,部分手机可能会受到限制,所以想要演示还是用as自带的模拟器
要改变屏幕的方向,只需在清单文件中加入一段码
android:screenOrientation=“landscape”(landscape为横屏,portrait为竖屏)
切换横屏竖屏可通过快捷键Ctrl+F11,或代码控制两种方式
ps:用代码控制,必须在接入布局之前
package com.example.myapplication5;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class ScreenOritationActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//通过代码设置屏幕方向
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//通过代码设置全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
//去标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_screen_oritation);
}
}
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
或
android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen"
窗口形式显示Activity
在清单文件中设置主题
android:theme="@android:style/Theme.DeviceDefault.Dialog"
package com.example.myapplication5;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
public class ScreenChangeActivity extends Activity {
int index=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_change);
System.out.println("ScreenChangeActivity-onCreate");
}
public void changeClick(View v){
index++;
System.out.println("index="+index);
}
}
可以看出每次横竖切换相当于Activity被重新创建了,状态值不被保存,为了保存当前Activity的状态,可以重写onSaveInstanceState方法保存状态
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
System.out.println("onSaveInstanceState");
outState.putInt("Index",index);
}
在onCreate中还原数据
//还原状态值
if (savedInstanceState!=null){
savedInstanceState.getInt("index",0);
}
不过在程序运行时,一些设备的配置可能会改变,Activity会重新启动,而销毁onSaveInstanceState当中保存的数据,我们需要在清单文件中设置android:configChanges属性,并使用onConfigurationChanged方法(改变配置)
写入方法
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
System.out.println("onConfigurationChanged");
}
用这个方法便不会在重新创建Activity
横屏竖屏切换时,不同布局方式,自动选择
在资源文件下新建一个目录layout-land(横屏布局)并复制所需文件到其中,然后改变布局样式。(一般在Android下找不到该目录,需要进入project/app/res去找)
通常情况下会发生这样的问题,我们在编辑短信的同时有电话打进来,那么接电话肯定是要启动另一个Activity,那么当前编辑短信的Activity所编辑的信息我们想暂时保存下来,等接完电话后回到该Activity时,可以继续编辑短信。该功能需要如何去实现呢?
Shared Preferences使用XML格式为Android应用提供一种永久的数据存储方式。它存储在文件系统的目录下,可以被处在同一应用中的所有Activity访问。Android提供了相关的API来处理这些数据而不需要程序员直接操作这些文件或者考虑数据同步问题。
package com.example.myapplication5;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
public class SharedPreferencesActivity extends AppCompatActivity {
private SharedPreferences sp;
private EditText editText_msg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shared_preferences);
editText_msg=findViewById(R.id.editText_msg);
//获取当前应用程序SharedPreferences对象 参数(文件名,模式)
sp=getSharedPreferences("msg", Context.MODE_PRIVATE);
}
//在该事件方法例还原数据
@Override
protected void onResume() {
super.onResume();
editText_msg.setText(sp.getString("msg",""));
SharedPreferences.Editor editor=sp.edit();
// editor.clear();//全部清空内容
editor.remove("msg");//清楚指定内容
editor.commit();
}
//在该事件方法里存储数据
@Override
protected void onPause() {
super.onPause();
String msg=editText_msg.getText().toString();//获取数据
if (TextUtils.isEmpty(msg)){//判断获取的内容是否为空
return;
}
SharedPreferences.Editor editor=sp.edit();
editor.putString("msg",msg);
editor.commit();//提交
}
}