Android_activity实现一个简单的新建联系表
项目展示:
第一个Activity用于显示联系人信息
第二个Activity输入联系人信息
要求:
运行“新建联系人”程序,结果如下图所示:
点击“新建联系人”按钮,打开输入信息界面并输入姓名、公司、电话号码、电子邮件,如下左图所示。填写之后点击完成按钮将数据回传给MainActivity,如下图所示
注意点
1、Activity必须在清单文件中注册,注册节点为<activity>;
2、Activity之间的跳转和传输数据使用Intent;
3、使用Activity回传数据需要用到startActivityForResult打开新的Activity;
4、回传数据界面需要设置setResult();方法设置结果数据并指定数据存放在Intent对象中。
下面我们分三步来实现这一个小案例
一、实现两个程序界面
1、显示联系人信息界面
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical" tools:context="com.example.asus.myapplication.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="128dip" android:layout_height="128dip" android:src="@drawable/img" /> <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="姓名" /> </LinearLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dip" android:gravity="center" android:text="电话" /> <TextView android:id="@+id/email" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="4dip" android:gravity="center" android:text="邮箱" /> </LinearLayout> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="新建联系人" /> </RelativeLayout> </LinearLayout>
2、输入联系人信息界面
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.asus.myapplication.Main2Activity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ImageView android:layout_width="128dip" android:layout_height="128dip" android:src="@drawable/img" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名" /> <EditText android:id="@+id/name2" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <EditText android:id="@+id/phone2" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:hint="电话" android:inputType="phone" /> <EditText android:id="@+id/email2" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:hint="邮箱" android:inputType="textEmailAddress" /> </LinearLayout> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="确认" /> </RelativeLayout> </LinearLayout>
二、实现在显示界面中对输入界面之间进行调用
参考: Activity超详解传送门
1、添加事件响应机制
package com.example.asus.myapplication; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { private Button bt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //按钮的点击事件 bt=(Button)findViewById(R.id.button); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, Main2Activity.class); startActivityForResult(intent, 0); } }); } }
三、实现在输入界面中输入信息传递给显示界面
可以开启另一个Activity通过传递一个Intent并且startActivity()方法启动它。描述了你希望启动的Activity。 Intent的两种用法:显示Intent和隐式Intent。 (1)显示Intent一般使用方法: Intent intent=newIntent(FirstActivity.this,SecondActivity.class); startActivity(intent); //简单的两行就能实现第一个活动跳转到第二个活动界面。 (2)隐式Intent一般使用方法: <!--首先需要在注册第二个活动时加入标签--> <!-- 必须指定CATEGORY_DEFAULT,只有这样startActivity(intent)才能找到 --> <!--注意 Intent Filter顾名思义就是Intent的过滤器,组件通过定义Intent Filter可以决定哪些隐式 --> <activity android:name=”.SecondAcivity”> <intent-filter> <action android:name=”包名.ACTION_START”/> <category android:name=”android.intent.category.DEFAULT”/> </intent-filter> </activity> 这样我们就可以用声明的标签来启动隐式Intent Intent intent=new Intent(“包名.ACTION_START”); startActivity(intent); (3)两者的使用区别 显式意图一般在应用的内部使用,因为在应用内部已经知道了组件的名称,直接调用就可以了。当一个应用要激活另一个应用中的Activity时,只能使用隐式意图,根据Activity配置的意图过滤器建一个意图,让意图中的各项参数的值都跟过滤器匹配,这样就可以激活其他应用中的Activity。所以,隐式意图是在应用与应用之间使用的。 Intent可以指定你希望启动或描述完成的动作(操作系统会为你选择合适的Activity,可能来自定不同的应用程序)。 你的应用程序或许希望执行一些动作,例如发送一份邮件、文件消息或者状态更新,使用你的Activity的数据。在这种情况下,你的应用程序或许没有它自己的Activity来完成这个动作,因此你可以促使设备上其它应用程序提供的Activity来完成你的动作。这才是Intent真正有价值的地方--你可以创建一个Intent描述一个你希望执行的动作,然后系统启动一个合适的activity从其它应用程序。如果有多种Activities可以处理这个Intent,那么 用户可以选择哪一个来执行。例如,如果你希望允许用户发送邮件,你可以创建下面的Intent: Intent intent= new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL,""); startActivity(intent);
一个Intent可以传输小量数据被启动的activity使用。 在启动活动时,Intent中提供了一系列putExtra()方法的重载,可以将我们需要传递的数据暂存在Intent中,在打开另一个活动时,从Intent中取出即可。 具体例子: (1)比如我们想要传递一个String字符串 String data=”Hello world!”; Intent intent=newIntent(FirstActivity.this,SecondActivity.class); Intent.putExtra(“extra_data”,data); //extra_data是一个标签,data是传入的数据。 //相当于Intent对象具有Map键值对功能。 startActivity(intent); 然后在SecondActivity的Oncreate方法里取出Intent存入的数据 Intent intent=getIntent(); String data=intent.getStringExtra(“extra_data”); //用String接收带extra_data标签的数据 Log.d(“SecondActivity”,data);//打印出data (2)新建一个Bundle对象 ,想该对象中加入键值对,然后将该对象加入Intent中 Intent intent=new Intent(); Bundle bundle = new Bundle(); bundle.putString("first", "zhang"); bundle.putInt("age", 20); intent.putExtras(bundle); intent.setClass(ActivityMain.this, SecondActivity.class); intent.putExtras(bundle); startActivity(intent); 然后在第二个Activity中接收 Bundle bundle = new Bundle(); bundle = this.getIntent().getExtras(); String a = bundle.getString("first"); int b = Integer.parseInt(bundle.getString("age")); (3)Intent传递Object对象 Android中Intent传递类对象提供了两种方式一种是 通过实现Serializable接口传递对象,一种是通过实现Parcelable接口传递对象。要求被传递的对象必须实现上述2种接口中的一种才能通过Intent直接传递。Intent中传递这2种对象的方法: Bundle.putSerializable(Key,Object); //实现Serializable接口的对象 Bundle.putParcelable(Key, Object); //实现Parcelable接口的对象 以下以最常用的Serializable方式为例 : 假设由登录界面(Login)跳转到主界面(MainActivity)传递的对象为登录的用户信息 User类 首先创建一个序列化类:User import java.io.Serializable; public class User implements Serializable { private int ID; private String UserName; private String PWD; public final void setID(int value) { ID = value; } public final int getID() { return ID; } public final void setUserName(String value) { UserName = value; } public final String getUserName() { return UserName; } public final void setPWD(String value) { PWD = value; } public final String getPWD() { return PWD; } } MainActivity传递内容 Intent intent = new Intent(); intent.setClass(MainActivity.this, SecondActivity.class); Bundle bundle = new Bundle(); bundle.putSerializable("user", user); intent.putExtras(bundle); this.startActivity(intent); SecondActivity接收 Intent intent = this.getIntent(); user=(User)intent.getSerializableExtra("user"); 以上就可以实现对象的传递。 补充: 如果传递的是List<Object>,可以把list强转成Serializable类型,而且object类型也必须实现了Serializable接口 Intent.putExtras(key, (Serializable)list) 接收 (List<YourObject>)getIntent().getSerializable(key)
1、创建一个User来存储临时信息
用findViewById()获取到Button对象
用setClass()函数启用class
package com.example.asus.myapplication; import java.io.Serializable; public class User implements Serializable{ private String name; private String phone; private String email; public User(String name, String phone, String email) { this.name = name; this.phone = phone; this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
Intent和bundle区别
intent是邮递员,bundle是信封。邮递员可以用信封来传递信息,也可以凭自己(内置的bundle)来传递信息。
2、在输入界面中获取数据对User进行存储
Intent传递Object对象
Android中Intent传递类对象提供了两种方式一种是 通过实现Serializable接口传递对象,一种是通过实现Parcelable接口传递对象。要求被传递的对象必须实现上述2种接口中的一种才能通过Intent直接传递
package com.example.asus.myapplication; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.Button; public class Main2Activity extends AppCompatActivity { private EditText texts[] = new EditText[3]; private int ids[] = new int[]{R.id.name2, R.id.phone2, R.id.email2}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); //初始化三个文本框 for(int i=0;i<ids.length;i++){ texts[i] = (EditText) findViewById(ids[i]); } //点击事件 findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.putExtra("user", new User(texts[0].getText().toString(), texts[1].getText().toString(), texts[2].getText().toString())); setResult(0, intent); finish(); } }); } }
parcelable和Serializable的区别又是什么呢?
Serializable的作用是保存对象的属性到本地文件,数据库,网络流等方便数据传输,也可程序之间传递。
parcelable的设计的目的是为了解决Serializable效率不高的问题,内存开销小,所以在内存间传递数据的方式用parcelable,缺点是不能持久化。
3、将数据回传到显示界面
Intent 作为一个负责组件间传递消息的信息对象,最重要的就是其包含的信息。实际上无论是显式还是隐式,Intent 发出的时候,系统对应的行为正是由 Intent 所包含信息的组合决定。一个 Intent 所包含的信息如下图:
//回调 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //所有控件的id int ids[] = new int[]{R.id.name, R.id.phone, R.id.email}; User user = (User) data.getExtras().get("user"); String values[] = new String[]{user.getName(), user.getPhone(), user.getEmail()}; //赋值 for(int i=0;i<ids.length;i++){ TextView text = (TextView) findViewById(ids[i]); text.setText(values[i]); } }
package com.example.asus.myapplication; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private Button bt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //按钮的点击事件 bt=(Button)findViewById(R.id.button); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, Main2Activity.class); startActivityForResult(intent, 0); } }); } //回调 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //所有控件的id int ids[] = new int[]{R.id.name, R.id.phone, R.id.email}; User user = (User) data.getExtras().get("user"); String values[] = new String[]{user.getName(), user.getPhone(), user.getEmail()}; //赋值 for(int i=0;i<ids.length;i++){ TextView text = (TextView) findViewById(ids[i]); text.setText(values[i]); } } }
题外: