一.“初次邂逅”
在我们构建设置界面的时候会用到ListPreference这个控件,默认(2.3之前)是单选,但我们现在想要多选,就像下图所示
二.“先看外表”
我们的项目结构如下:
首先我们先看布局文件
preference_layout.xml
<?
xml version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
<
PreferenceScreen xmlns:android
=
"
http://schemas.android.com/apk/res/android
"
>
<
com.u0fly.MutiSelectListPreference.MutiSelectListPreference
android:defaultValue
=
"
a
"
android:key
=
"
muti_select_list_preference
"
android:title
=
"
@string/title_muti_select_list_preference
"
android:dialogTitle
=
"
@string/dialog_title_muti_select_list_preference
"
android:summary
=
"
@string/summary_muti_select_list_preference
"
android:entries
=
"
@array/entries_muti_select_list_preference
"
android:entryValues
=
"
@array/entries_values_muti_select_list_preference
"
>
</
com.u0fly.MutiSelectListPreference.MutiSelectListPreference
>
</
PreferenceScreen
>
这样我们就构建出上面一开始我们看到的那个多选的对话框了
我们用<com.u0fly.MutiSelectListPreference.MutiSelectListPreference>代替了我们之前系统提供的ListPreference
当然我们还要自己构建一个相应的类,该类继承自ListPreference
里面要重写下面这两个方法:
onPrepareDialogBuilder和onDialogClosed
下面是string.xml和arrays.xml中的内容,大家可以根据自己的需要进行修改:
<?
xml version="1.0" encoding="utf-8"
?>
<
resources
>
<
string
name
="hello"
>
Hello World, MutiSelectListPreference!
</
string
>
<
string
name
="app_name"
>
MutiSelectListPreference
</
string
>
<
string
name
="title_muti_select_list_preference"
>
多选设置
</
string
>
<
string
name
="dialog_title_muti_select_list_preference"
>
请选择多个选项
</
string
>
<
string
name
="summary_muti_select_list_preference"
>
支持多选的设置
</
string
>
</
resources
>
<?
xml version="1.0" encoding="utf-8"
?>
<
resources
>
<
string-array
name
="entries_muti_select_list_preference"
>
<
item
>
item a
</
item
>
<
item
>
item b
</
item
>
<
item
>
item c
</
item
>
<
item
>
item d
</
item
>
<
item
>
item e
</
item
>
<
item
>
item f
</
item
>
</
string-array
>
<
string-array
name
="entries_values_muti_select_list_preference"
>
<
item
>
a
</
item
>
<
item
>
b
</
item
>
<
item
>
c
</
item
>
<
item
>
d
</
item
>
<
item
>
e
</
item
>
<
item
>
f
</
item
>
</
string-array
>
</
resources
>
三.“深入了解”
接下来我们来看看构建出这个多选设置的类 MutiSelectListPreference
package
com.u0fly.MutiSelectListPreference;
import
android.app.AlertDialog.Builder;
import
android.content.Context;
import
android.content.DialogInterface;
import
android.preference.ListPreference;
import
android.util.AttributeSet;
import
android.util.Log;
public
class
MutiSelectListPreference
extends
ListPreference {
private
static
final
String TAG
=
"
u0fly -------->
"
;
private
static
final
String SEPARATOR
=
"
u0fly_@#asdf*&_ylf0u
"
;
private
boolean
[] mClickedDialogEntryIndices;
public
MutiSelectListPreference(Context context, AttributeSet attrs) {
super
(context, attrs);
//
TODO Auto-generated constructor stub
mClickedDialogEntryIndices
=
new
boolean
[getEntries().length];
}
@Override
public
void
setEntries(CharSequence[] entries) {
super
.setEntries(entries);
mClickedDialogEntryIndices
=
new
boolean
[entries.length];
}
public
MutiSelectListPreference(Context context) {
this
(context,
null
);
}
@Override
protected
void
onDialogClosed(
boolean
positiveResult) {
//
TODO Auto-generated method stub
CharSequence[] entryValues
=
getEntryValues();
if
(positiveResult
&&
entryValues
!=
null
) {
StringBuffer value
=
new
StringBuffer();
for
(
int
i
=
0
; i
<
entryValues.length; i
++
) {
if
(mClickedDialogEntryIndices[i]) {
value.append(entryValues[i]).append(SEPARATOR);
}
}
if
(callChangeListener(value)) {
String val
=
value.toString();
if
(val.length()
>
0
)
val
=
val.substring(
0
, val.length()
-
SEPARATOR.length());
setValue(val);
}
}
}
@Override
protected
void
onPrepareDialogBuilder(Builder builder) {
//
TODO Auto-generated method stub
CharSequence[] entries
=
getEntries();
CharSequence[] entryValues
=
getEntryValues();
Log.d(TAG ,
"
onPrepareDialogBuilder entries =
"
+
entries.toString()
+
"
entryValues =
"
+
entryValues.toString());
if
(entries
==
null
||
entryValues
==
null
||
entries.length
!=
entryValues.length) {
throw
new
IllegalStateException(
"
ListPreference requires an entries array and an entryValues array which are both the same length
"
);
}
restoreCheckedEntries();
builder.setMultiChoiceItems(entries, mClickedDialogEntryIndices,
new
DialogInterface.OnMultiChoiceClickListener() {
public
void
onClick(DialogInterface dialog,
int
which,
boolean
val) {
Log.d(
"
u0fly------>
"
,
"
OnMultiChoiceClickListener val =
"
+
val);
mClickedDialogEntryIndices[which]
=
val;
}
});
}
public
static
String[] parseStoredValue(CharSequence val) {
Log.d(
"
u0fly----->
"
,
"
parseStoredValue val =
"
+
val.toString());
if
(
""
.equals(val))
return
null
;
else
return
((String) val).split(SEPARATOR);
}
private
void
restoreCheckedEntries() {
CharSequence[] entryValues
=
getEntryValues();
String[] vals
=
parseStoredValue(getValue());
if
(vals
!=
null
) {
Log.d(
"
u0fly----->
"
,
"
restoreCheckedEntries vals =
"
+
vals);
for
(
int
j
=
0
; j
<
vals.length; j
++
) {
Log.d(
"
u0fly----->
"
,
"
restoreCheckedEntries val without trim =
"
+
vals[j]);
String val
=
vals[j].trim();
Log.d(
"
u0fly----->
"
,
"
restoreCheckedEntries val =
"
+
val);
for
(
int
i
=
0
; i
<
entryValues.length; i
++
) {
CharSequence entry
=
entryValues[i];
if
(entry.equals(val)) {
mClickedDialogEntryIndices[i]
=
true
;
break
;
}
}
}
}
}
}
前面的布局文件就是通过这个类来构建出多选设置界面的
通过com.u0fly.MutiSelectListPreference.MutiSelectListPreference
main.java 通过xml的形式加载设置界面,前面的文章我们也用过,通过监听onPreferenceChange可以添加具体操作
具体参考:http://www.cnblogs.com/u0fly/archive/2011/05/06/2038623.html
/*
*@author u0fly,2011-5-11
*
*Blog: http://www.cnblogs.com/u0fly/
*
*/
package com.u0fly.MutiSelectListPreference;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Main extends PreferenceActivity{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preference_layout);
}
}