Some new preferences features.
- You can add arbitrary stuff at the bottom of the header list.
- You can associated an intent with a header to have that launched
when the header is clicked.
- You can change the current header when the header list is rebuilt
after the first time.
Change-Id: I889512beff0c2902a790434e5cde9ce6df74d0c2
diff --git a/api/current.xml b/api/current.xml
index d261a97..b79e6d1 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -139228,6 +139228,17 @@
visibility="public"
>
</method>
+<method name="onGetNewHeader"
+ return="android.preference.PreferenceActivity.Header"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="onHeaderClick"
return="void"
abstract="false"
@@ -139295,6 +139306,19 @@
<parameter name="preference" type="android.preference.Preference">
</parameter>
</method>
+<method name="setListFooter"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.view.View">
+</parameter>
+</method>
<method name="setPreferenceScreen"
return="void"
abstract="false"
@@ -139428,6 +139452,16 @@
visibility="public"
>
</field>
+<field name="intent"
+ type="android.content.Intent"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="summary"
type="java.lang.CharSequence"
transient="false"
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 70a2b80..4889c19 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -42,6 +42,7 @@
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
@@ -158,6 +159,8 @@
private HeaderAdapter mAdapter;
+ private FrameLayout mListFooter;
+
private View mPrefsContainer;
private boolean mSinglePane;
@@ -189,6 +192,10 @@
case MSG_BUILD_HEADERS:
onBuildHeaders(mHeaders);
mAdapter.notifyDataSetChanged();
+ Header header = onGetNewHeader();
+ if (header != null && header.fragment != null) {
+ switchToHeader(header.fragment, header.fragmentArguments);
+ }
break;
}
}
@@ -287,6 +294,11 @@
* instantiated.
*/
public Bundle fragmentArguments;
+
+ /**
+ * Intent to launch when the preference is selected.
+ */
+ public Intent intent;
}
@Override
@@ -295,6 +307,7 @@
setContentView(com.android.internal.R.layout.preference_list_content);
+ mListFooter = (FrameLayout)findViewById(com.android.internal.R.id.list_footer);
mPrefsContainer = findViewById(com.android.internal.R.id.prefs);
boolean hidingHeaders = onIsHidingHeaders();
mSinglePane = hidingHeaders || !onIsMultiPane();
@@ -446,6 +459,16 @@
}
/**
+ * Called after the header list has been updated ({@link #onBuildHeaders}
+ * has been called and returned due to {@link #invalidateHeaders()}) to
+ * specify the header that should now be selected. The default implementation
+ * returns null to keep whatever header is currently selected.
+ */
+ public Header onGetNewHeader() {
+ return null;
+ }
+
+ /**
* Called when the activity needs its list of headers build. By
* implementing this and adding at least one item to the list, you
* will cause the activity to run in its modern fragment mode. Note
@@ -498,7 +521,7 @@
Bundle curBundle = null;
- int outerDepth = parser.getDepth();
+ final int outerDepth = parser.getDepth();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -524,7 +547,27 @@
if (curBundle == null) {
curBundle = new Bundle();
}
- getResources().parseBundleExtras(parser, curBundle);
+
+ final int innerDepth = parser.getDepth();
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String innerNodeName = parser.getName();
+ if (innerNodeName.equals("extra")) {
+ getResources().parseBundleExtra("extra", attrs, curBundle);
+ XmlUtils.skipCurrentTag(parser);
+
+ } else if (innerNodeName.equals("intent")) {
+ header.intent = Intent.parseIntent(getResources(), parser, attrs);
+
+ } else {
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+
if (curBundle.size() > 0) {
header.fragmentArguments = curBundle;
curBundle = null;
@@ -546,6 +589,16 @@
}
+ /**
+ * Set a footer that should be shown at the bottom of the header list.
+ */
+ public void setListFooter(View view) {
+ mListFooter.removeAllViews();
+ mListFooter.addView(view, new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT));
+ }
+
@Override
protected void onStop() {
super.onStop();
@@ -633,10 +686,14 @@
* @param position The header's position in the list.
*/
public void onHeaderClick(Header header, int position) {
- if (mSinglePane) {
- startWithFragment(header.fragment, header.fragmentArguments);
- } else {
- switchToHeader(header.fragment, header.fragmentArguments);
+ if (header.fragment != null) {
+ if (mSinglePane) {
+ startWithFragment(header.fragment, header.fragmentArguments);
+ } else {
+ switchToHeader(header.fragment, header.fragmentArguments);
+ }
+ } else if (header.intent != null) {
+ startActivity(header.intent);
}
}
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index eeba18e..fe950b2 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -29,12 +29,25 @@
android:layout_height="0px"
android:layout_weight="1">
- <ListView android:id="@android:id/list"
+ <LinearLayout
+ android:orientation="vertical"
android:layout_width="0px"
android:layout_height="match_parent"
- android:layout_weight="1"
- android:drawSelectorOnTop="false"
- android:scrollbarAlwaysDrawVerticalTrack="true" />
+ android:layout_weight="1">
+
+ <ListView android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1"
+ android:drawSelectorOnTop="false"
+ android:scrollbarAlwaysDrawVerticalTrack="true" />
+
+ <FrameLayout android:id="@+id/list_footer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="0" />
+
+ </LinearLayout>
<FrameLayout android:id="@+id/prefs"
android:layout_width="0px"