建立、配置和使用Activity——启动其他Activity并返回结果
Activity还提供了一个startActivityForResult(Intent intent,int requestCode)方法来启动其他Activity。该方法用于启动指定Activity,而且期望获取指定Activity返回的结果。这种请求对于实际应用也是很常见的,例如应用程序第一个界面需要用户进行选择一旦需要选择的列表数据比较复杂,必须启动另一个Activity让用户选择。当用户在第二个Activity选择完成后,程序返回第一个Activity,第一个Activity必须能获取并显示用户在第二个Activity选择的结果。在这种应用场景下,也是通过Bundle进行数据交换的。
为了获取被启动Activity所返回的结果,需要从两方面着手:
- 当前Activity需要重写onActivityResult(int requestCode,int resultCode,Intent intent),当被启动的Activity返回结果时,该方法将会被触发,其中requestCode代表请求码,而resultCode代表Activity返回的结果码,这个结果码也是由开发者根据业务自行设定的。
- 被启动的Activity需要调用setResult()方法设置处理结果。
一个Activity中可能包含多个按钮,并调用多个startActivityForResult()方法来打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统都将回调前面Activity的onActivityResult(int requestCode,int resultCode,Intent data)方法。为了知道该方法是由哪个请求的结果所触发的,可利用requestCode请求码;为了知道返回的数据来自于哪个新的Activity,可利用requestCode结果码。
下面通过一个示例来介绍如何启动Activity并获取被启动Activity的结果。
实例:用第二个Activity让用户选择信息
下面程序也包含两个Activity,第一个Activity的界面布局比较简单,它只包含一个按钮和一个文本框。界面布局文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <Button android:id="@+id/bn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="选择您所在城市" /> <EditText android:id="@+id/city" android:layout_width="fill_parent" android:layout_height="wrap_content" android:editable="false" android:cursorVisible="false" > </EditText> </LinearLayout>
第一个Activity对应的Java代码如下:
package com.example.studyactivity; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class ActivityForResult extends Activity { Button bn; EditText city; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_activity_for_result); //获取上面的组件 bn=(Button)findViewById(R.id.bn); city=(EditText)findViewById(R.id.city); //为按钮绑定事件监听器 bn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub //创建需要对应于目标Activity的Intent Intent intent=new Intent(ActivityForResult.this,SelectCityActivity.class); //启动指定Activity并等待返回的结果,其中0是请求码,用于标识该请求 startActivityForResult(intent,0); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // TODO Auto-generated method stub //当requestCode、resultCode同时为0时,也就是处理特定的结果 if(requestCode==0&&resultCode==0) { //取出Intent里面的Extras数据 Bundle data=intent.getExtras(); //取出Bundle中的数据 String resultCity=data.getString("city"); //修改city文本框的内容 city.setText(resultCity); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_for_result, menu); return true; } }
上面的程序中粗体字代码用于启动ActivityForResult,并等待该Activity返回的结果——但问题是:该Activity如何获取ActivityForResult返回的结果呢?当前Activity启动SelectCityActivity之后,SelectCityActivity何时返回结果是不确定的,因此当前Activity无法去获取SelectCityActivity返回的结果。
为了让当前Activity获取SelectCityActivity所返回的结果,开发者应该重写onActivityResult()方法——当被启动的SelectCityActivity返回结果时,onActivityResult()方法将会被回调。因此上面代码重写了onActivityResult()方法。
运行程序,将看到如图4.14所示的界面。
单击图4.14所示界面中“选择您所在的城市”按钮,系统将会启动SelectCityActivity,该SelectCityActivity将会显示一个可展开的列表。该SelectCityActivity无需界面布局文件。该SelectCityActivity的Java代码如下。
package com.example.studyactivity; import android.os.Bundle; import android.app.Activity; import android.app.ExpandableListActivity; import android.content.Intent; import android.database.DataSetObserver; import android.view.Gravity; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class SelectCityActivity extends ExpandableListActivity { //定义省份数组 private String[] provinces=new String[]{"广东","广西","湖南"}; private String[][] cities=new String[][]{ {"广州","深圳","珠海","中山"}, {"贵州","柳州","南宁","北海"}, {"长沙","岳阳","衡阳","株洲"} }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ExpandableListAdapter adapter=new ExpandableListAdapter(){ @Override public boolean areAllItemsEnabled() { // TODO Auto-generated method stub return false; } @Override public Object getChild(int groupPosition, int childPosition) { // TODO Auto-generated method stub return cities[groupPosition][childPosition]; } @Override public long getChildId(int groupPosition, int childPosition) { // TODO Auto-generated method stub return childPosition; } //该方法决定每个子选项的外观 @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { // TODO Auto-generated method stub TextView textView=getTextView(); textView.setText(getChild(groupPosition,childPosition).toString()); return textView; } private TextView getTextView() { AbsListView.LayoutParams lp=new AbsListView.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT,64); TextView textView=new TextView(SelectCityActivity.this); textView.setLayoutParams(lp); textView.setGravity(Gravity.CENTER_VERTICAL|Gravity.LEFT); textView.setPadding(36, 0, 0, 0); textView.setTextSize(20); return textView; } @Override public int getChildrenCount(int groupPosition) { // TODO Auto-generated method stub return cities[groupPosition].length; } @Override public long getCombinedChildId(long groupId, long childId) { // TODO Auto-generated method stub return 0; } @Override public long getCombinedGroupId(long groupId) { // TODO Auto-generated method stub return 0; } @Override public Object getGroup(int groupPosition) { // TODO Auto-generated method stub return provinces[groupPosition]; } @Override public int getGroupCount() { // TODO Auto-generated method stub return provinces.length; } @Override public long getGroupId(int groupPosition) { // TODO Auto-generated method stub return groupPosition; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { // TODO Auto-generated method stub LinearLayout ll=new LinearLayout(SelectCityActivity.this); ll.setOrientation(0); ImageView logo=new ImageView(SelectCityActivity.this); ll.addView(logo); TextView textView=getTextView(); textView.setText(getGroup(groupPosition).toString()); ll.addView(textView); return ll; } @Override public boolean hasStableIds() { // TODO Auto-generated method stub return false; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { // TODO Auto-generated method stub return true; } @Override public boolean isEmpty() { // TODO Auto-generated method stub return false; } @Override public void onGroupCollapsed(int groupPosition) { // TODO Auto-generated method stub } @Override public void onGroupExpanded(int groupPosition) { // TODO Auto-generated method stub } @Override public void registerDataSetObserver(DataSetObserver observer) { // TODO Auto-generated method stub } @Override public void unregisterDataSetObserver(DataSetObserver observer) { // TODO Auto-generated method stub } }; //设置该窗口显示列表 setListAdapter(adapter); getExpandableListView().setOnChildClickListener(new OnChildClickListener(){ @Override public boolean onChildClick(ExpandableListView parent, View source, int groupPosition, int childPosition, long id) { // TODO Auto-generated method stub //获取启动该Activity之间的Activity对应的Intent Intent intent=getIntent(); intent.putExtra("city", cities[groupPosition][childPosition]); //设置该SelectActivity的结果码,并设置结束之后退回的Activity SelectCityActivity.this.setResult(0,intent); //结束SelectCityActivity SelectCityActivity.this.finish(); return false; } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.select_city, menu); return true; } }
上面的Activity只是一个普通的显示可展开列表的Activity,程序还为该Activity的各子列表项绑定了事件监听器,当用户单击子列表项时,该Activity将会把用户选择城市返回给上一个Activity。
当上一个Activity获取SelectCityActivity选择城市之后,将会把该程序显示在图4.14所示界面右边的文本框内。