前言
往者不可谏,来者犹可追。
建立自己的Activity需要继承Activity基类。当然,在不同的场景下,你也可以继承Activity的子类来简化开发。例如,如果应用程序界面只包括列表,则可以让应用程序继承ListActivity;如果应用程序界面需要实现标签页效果,则可以让应用程序继承TabActivity。下面我来介绍一下几个Activity的子类结合的例子。
LauncherActivity
LauncherActivity继承了ListActivity,因此它本质上也是一个开发列表界面的Activity,但它开发出来的列表界面与普通列表界面有所不同。它开发出来的列表界面中的每个列表项都对应于一个Intent,因此当用户单击不同的列表项时,应用程序会自动启动相应的Activity。
与使用普通ListActivity不同的是,继承LauncherActivity时通常应该重写Intent intentForPosition(int position)方法,该方法根据不同列表项返回不同的Intent(用于启动不同的Activity)。
MainActivity.java
public class MainActivity extends LauncherActivity {
//定义两个Activity的名称
String []names = {"设置程序参数","动物世界"};
//定义两个Activity对应的实现类
Class[] clazz = {PreferenceActivityTest.class
,ExpandableListActivityTest.class};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, names);
setListAdapter(adapter);
}
@Override
protected Intent intentForPosition(int position) {
return new Intent(MainActivity.this, clazz[position]);
}
}
效果
Screenshot_20171101-093217.png
下面我们来继续完善这个程序,当你点击不同的列表项,跳转到不同的Activity。
ExpandableListAcitviy
ExpandableListAcitviy的用法与ExpandableListView的用法基本相似,只要为该Activity传入一个ExpandableListAdapter对象即可,接下来ExpandableListAcitviy将会生成一个显示可展开列表的窗口。
ExpandableListAcitviyTest.java
public class ExpandableListActivityTest extends android.app.ExpandableListActivity {
String[] armTypes = { "企鹅", "熊猫", "老虎" };
String[][] arms = { { "白企鹅", "黑企鹅", "小企鹅" }, { "大熊猫", "母熊猫", "小熊猫" }, { "打老虎", "母老虎", "小老虎" } };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExpandableListAdapter adapter = new BaseExpandableListAdapter() {
private TextView getTextView() {
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 64);
TextView textView = new TextView(ExpandableListActivityTest.this);
textView.setLayoutParams(lp);
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
textView.setPadding(36, 0, 0, 0);
textView.setTextSize(20);
return textView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
@Override
public boolean hasStableIds() {
return true;
}
// 该方法决定每个组选项的外观
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
LinearLayout ll = new LinearLayout(ExpandableListActivityTest.this);
ll.setOrientation(LinearLayout.HORIZONTAL);
ImageView logo = new ImageView(ExpandableListActivityTest.this);
logo.setImageResource(R.drawable.ic_launcher);
ll.addView(logo);
TextView textView = getTextView();
textView.setText(getGroup(groupPosition).toString());
ll.addView(textView);
return ll;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public int getGroupCount() {
return armTypes.length;
}
@Override
public Object getGroup(int groupPosition) {
return armTypes[groupPosition];
}
@Override
public int getChildrenCount(int groupPosition) {
return arms[groupPosition].length;
}
// 该方法决定每个子选项的外观
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
ViewGroup parent) {
TextView textView = getTextView();
textView.setText(getChild(groupPosition, childPosition).toString());
return textView;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return arms[groupPosition][childPosition];
}
};
setListAdapter(adapter);
}
}
效果
点击MainActivity中的动物世界选项,将会看到如下效果。
Screenshot_20171101-093757.png
PreferenceActivity结合PreferenceFragment的使用
PreferenceActivity是一个非常有用的基类,当我们开发一个Android应用程序时,不可避免地需要进行选项设置,这些选项设置会以参数的形式保存,习惯上我们会用Preferences进行保存。
为了创建一个PreferenceActivity,需要先创建一个对应的界面布局。从Android3.0开始,Android不再推荐直接让PreferenceActivity加载选项设置的布局文件,而是建议将PreferenceActivity与PreferenceFragment结合使用,其中PreferenceActivity只负责加载选项设置列表的布局文件,PreferenceFragment才负责加载选项设置的布局文件。
PreferenceActivityTest.java
public class PreferenceActivityTest extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 该方法用于为该界面设置一个标题按钮 if (hasHeaders()) { Button button = new Button(this); button.setText("设置操作"); // 将该按钮添加到该界面上 setListFooter(button); } } // 重写该方法,负责加载界面布局文件 @Override public void onBuildHeaders(List
target) { // 加载选项设置列表的布局文件 loadHeadersFromResource(R.layout.preference_header, target); } // 重写该方法,验证各PreferenceFragment是否有效 @Override protected boolean isValidFragment(String fragmentName) { return true; } public static class Prefs1Fragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.layout.preference); } } public static class Prefs2Fragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.layout.display_prefs); //获取传入该Fragment的参数 String website = getArguments().getString("website"); Toast.makeText(getActivity(), website, Toast.LENGTH_SHORT).show(); } } }
preference_header.xml
效果
Screenshot_20171101-103919.png
display_prefs.xml
效果
Screenshot_20171101-104042.png
preference.xml
/>
目前为止,该应用程序有三个Activity类,但这三个Activity还不能使用,必须在AndroidManifest.xml清单文件中配置Activity才行。
配置Activity时通常指定如下几个属性。
- name:指定该Activity的实现类的类名。
- icon:指定该Activity对应的图标。
- label:指定该Activity的标签。
- exported:指定该Activity是否允许被其他应用调用。
- launchMode:指定该Activity的加载模式,该属性支持standard、singleTop、singleTask和singleInstance这4种加载模式。