(本系列基于Jelly Bean,Android OS4.2,API 17版本)
就算是最简单的应用程序也会拥有不止一项功能,因此我们经常要应对多个Activity。主Activity随应用程序启动而启动,可以通过触发事件开启另外的Activity。要想激活应用中的某个特定组件,可以用显式命名的Intent来实现,也可以采用隐式Intent,尽可能选用隐式的,它能为模块化功能提供强大的框架。
隐式Intent不需要指定要使用哪个组件,它们通过过滤器指定所需的功能,而Android系统必须决定使用哪个组件是最佳选择。Intent过滤器可以是动作action,数据data或者分类category。最常用的Intent过滤器是动作,(本例用的是category,IntentFilter中可以有多个Category,可以比Intent中的Category多,但是必须包含Intent对象中所有的Category)。
下面是使用隐式Intent启用Activity的具体步骤。
(1)声明Intent,同时指定合适的过滤器(如ACTION_VIEW,ACTION_WEB_SEARCH等)。
(2)为运行Activity所需的该Intent附加额外信息。
(3)将该Activity传递给startActivy()方法。
本例另外一个技巧就是,提供给用户选择列表,供用户点选。这一功能是通过ListActiviy实现。ListActivity是Activity的一个子类,它会根据用户选择来触发对应事件。下面是创建选择列表的步骤:
(1)创建一个扩展ListActivity的类。
public class AppNavHomeActivity extends ListActivity{
//...
}
(2)创建一个存储各个选项信息(本例是名称和Intent对象)的List,
static class SampleInfo{/*...*/}
...
private List<SampleInfo> mItems;
private List<SampleInfo> querySampleActivities(){/*...*/}
(3)以Adapter为参数调用setListAdapter(),并指定选择列表及一个布局:
class SampleAdapter extends BaseAdapter{
//...
//指定布局方法
public View getView(){...}
}
setListAdapter(new SampleAdapter(querySampleActivities()));
在这里简单介绍下Adapter的概念和用法。 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带。在常见的View(ListView,GridView)等地方都需要用到Adapter,换句话说Adapter的作用就是把data装配好以后展示在View上。set方法用来设置,get方法用来获取。更详尽的介绍可以自行查找学习。
(4)启动OnItemClickListener或者实现onListItemClick方法以确定选中了哪个选项,并做出对应动作:
protected void onListItemClick(ListView lv, View v, int pos, long id) {
SampleInfo info = (SampleInfo) getListAdapter().getItem(pos);
startActivity(info.intent);
}
下面写出主Activity类,大家可以对照学习:
import android.app.ListActivity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class AppNavHomeActivity extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new SampleAdapter(querySampleActivities()));
}
@Override
protected void onListItemClick(ListView lv, View v, int pos, long id) {
SampleInfo info = (SampleInfo) getListAdapter().getItem(pos);
startActivity(info.intent);
}
protected List<SampleInfo> querySampleActivities() {
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setPackage(getPackageName());
//调用方法addCatgory来为Intent添加Category
intent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
PackageManager pm = getPackageManager();
List<ResolveInfo> infos = pm.queryIntentActivities(intent, 0);
ArrayList<SampleInfo> samples = new ArrayList<SampleInfo>();
final int count = infos.size();
for (int i = 0; i < count; i++) {
final ResolveInfo info = infos.get(i);
final CharSequence labelSeq = info.loadLabel(pm);
String label = labelSeq != null ? labelSeq.toString() : info.activityInfo.name;
Intent target = new Intent();
target.setClassName(info.activityInfo.applicationInfo.packageName,info.activityInfo.name);
SampleInfo sample = new SampleInfo(label, target);
samples.add(sample);
}
return samples;
}
static class SampleInfo {
String name;
Intent intent;
SampleInfo(String name, Intent intent) {
this.name = name;
this.intent = intent;
}
}
class SampleAdapter extends BaseAdapter {
private List<SampleInfo> mItems;
public SampleAdapter(List<SampleInfo> items) {
mItems = items;
}
@Override
public int getCount() {
return mItems.size();
}
@Override
public Object getItem(int position) {
return mItems.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(android.R.layout.simple_list_item_1,parent, false);
convertView.setTag(convertView.findViewById(android.R.id.text1));
}
TextView tv = (TextView) convertView.getTag();
tv.setText(mItems.get(position).name);
return convertView;
}
}
}
本例中的几个子Activity各不相同,用到了不同的知识点,感兴趣的同学可以进一步研究。