前言
往者不可谏,来者犹可追。
建立自己的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<String> adapter = new ArrayAdapter<String>(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<Header> 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
<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 指定启动PreferenceFragment的列表项 -->
<header
android:fragment="com.张敦锋.activitydemo.PreferenceActivityTest$Prefs1Fragment"
android:icon="@drawable/ic_launcher"
android:summary="设置应用的相关选项"
android:title="程序选项设置" />
<!-- 指定启动preferenceFragment的列表 -->
<header
android:fragment="com.张敦锋.activitydemo.PreferenceActivityTest$Prefs2Fragment"
android:icon="@drawable/ic_launcher"
android:summary="设置显示界面的相关选项"
android:title="界面选项设置" >
<!-- 使用extra可向Activity传入额外数据 -->
<extra
android:name="website"
android:value="www.baidu.com" />
</header>
<!-- 使用Intent启动指定Activity的列表项 -->
<header
android:icon="@drawable/ic_launcher"
android:summary="使用Intent启动某个Activity"
android:title="使用Intent" >
<intent android:action="android.intent.action.VIEW"
android:data="http://www.baidu.com"/>
</header>
</preference-headers>
效果
Screenshot_20171101-103919.png
display_prefs.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="背景灯光组" >
<!-- 通过列表框选择灯光强度 -->
<ListPreference
android:dialogTitle="请选择灯光强度"
android:entries="@array/light_strength_list"
android:entryValues="@array/light_value_list"
android:key="light"
android:summary="请选择灯光强度"
android:title="灯光强度" >
</ListPreference>
</PreferenceCategory>
<PreferenceCategory android:title="文字显示组" >
<!-- 通过SwitchPreference设置是否自动滚屏 -->
<SwitchPreference
android:defaultValue="true"
android:key="autoScroll"
android:summaryOn="自动滚屏:开启"
android:summaryOff="自动滚屏:关闭"
android:title="自动滚屏" />
</PreferenceCategory>
</PreferenceScreen>
效果
Screenshot_20171101-104042.png
preference.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置系统铃声 -->
<RingtonePreference
android:ringtoneType="all"
android:title="设置铃声"
android:summary="选择铃声"
android:showDefault="true"
android:key="ring_key"
android:showSilent="true"
/>
<!-- 通过输入框填写用户名 -->
<EditTextPreference
android:key="name"
android:title="填写用户名"
android:summary="填写您的用户名"
android:dialogTitle="您所使用的用户名为:"/>
<!-- 通过列表框选择性别 -->
<ListPreference
android:key="gender"
android:title="性别"
android:summary="选择您的性别"
android:dialogTitle="ListPreference"
android:entries="@array/gender_name_list"
android:entryValues="@array/gender_value_list"/>
/>
<PreferenceCategory android:title="系统功能设置组">
<CheckBoxPreference
android:key="autoSave"
android:title="自动保存进度"
android:summaryOn="自动保存:开启"
android:summaryOff="自动保存:关闭"
android:defaultValue="true"/>
</PreferenceCategory>
</PreferenceScreen>
目前为止,该应用程序有三个Activity类,但这三个Activity还不能使用,必须在AndroidManifest.xml清单文件中配置Activity才行。
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.张敦锋.activitydemo.ExpandableListActivityTest"
android:label="动物世界" >
</activity>
<activity
android:name="com.张敦锋.activitydemo.PreferenceActivityTest"
android:label="设置程序参数" >
</activity>
</application>
配置Activity时通常指定如下几个属性。
- name:指定该Activity的实现类的类名。
- icon:指定该Activity对应的图标。
- label:指定该Activity的标签。
- exported:指定该Activity是否允许被其他应用调用。
- launchMode:指定该Activity的加载模式,该属性支持standard、singleTop、singleTask和singleInstance这4种加载模式。
上面的程序运行并设置相应的程序参数,系统将会在/data/data/zdf.halo/shared_prefs/路径下生成一个xml文件,里面保存了你设置的参数信息。这里直接使用PreferenceActivity,我们完全不用去考虑Preference的读写,它会为我们处理一切。还有另一种方法,SharedPreference,它的作用很大,具体介绍请关注后续的文章。