使用 StringSet 的自定义首选项
Custom Preference with a StringSet
我有一个文件夹列表,我想在首选项中显示为字符串列表。我正在通过 SharedPreferences.Editor.putStringSet()
存储文件夹。用户可以单击一行以删除该条目。
我不确定如何在自定义中显示这些值 Preference
;一个 ListView 将是理想的。内置首选项不支持此用例,并且 Preference.getPersistedStringSet
已隐藏 "pending API approval",显然已隐藏多年,因此自定义首选项将无法轻松工作。
我可以在自定义 Preference
中使用带有静态辅助方法的分隔字符串来确保对 SharedPreferences.Editor.putString()
(而不是 putStringSet
)的调用格式正确,但这是有点马虎。有更好的想法吗?
下面是保存一组字符串的例子:
SharedPreferences sp = SharedPreferences.getDefaultSharedPreferences(this);
//Save the values
SharedPreferences.Editor editor = sp.edit();
Set<String> set = new HashSet<String>();
set.addAll(listOfFolders);
editor.putStringSet("key", set);
editor.commit();
//Get the values
Set<String> set = sp.getStringSet("key", null);
希望这对你有用。
编辑:
您还可以使用具有一组条目和条目值的 ListPreference。您可以随时以编程方式更改这些条目,例如:
listPref.setEntries(R.array.listArray);
listPref.setEntryValues(R.array.listValues);
您还可以像这样持久化数据:
listPref.setPersistent(true);
更多信息:
http://developer.android.com/reference/android/preference/ListPreference.html
所以我创建了一个自定义 DialogPreference
,因为现有视图本来就是 poor/confusing 用户体验。它实际上 link 到(并且需要) StringSet
首选项键并允许用户删除条目。您可以修改 onClick
以使其表现不同。
public class RemovableListPreference extends DialogPreference implements OnClickListener
{
private static final String androidns="http://schemas.android.com/apk/res/android";
private ListView mListView;
private ArrayAdapter<String> mAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1);
private TextView mSplashText,mValueText;
private String mPreferenceKey;
private Context mContext;
private String mDialogMessage;
public RemovableListPreference(Context context, AttributeSet attrs) {
super(context,attrs);
mContext = context;
// Message attribute for the alert dialog
int mDialogMessageId = attrs.getAttributeResourceValue(androidns, "dialogMessage", 0);
if(mDialogMessageId == 0)
mDialogMessage = attrs.getAttributeValue(androidns, "dialogMessage");
else
mDialogMessage = mContext.getString(mDialogMessageId);
// Key attribute for the view, used to automatically update the preferences
int preferenceId = attrs.getAttributeResourceValue(androidns, "key", -1);
if (preferenceId == -1)
throw new RuntimeException(RemovableListPreference.class.getSimpleName() + " requires a preference key (android:key)");
else
mPreferenceKey = mContext.getString(preferenceId);
}
@Override
protected View onCreateDialogView() {
LinearLayout.LayoutParams params;
LinearLayout layout = new LinearLayout(mContext);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(6,6,6,6);
mSplashText = new TextView(mContext);
if (mDialogMessage != null)
mSplashText.setText(mDialogMessage);
layout.addView(mSplashText);
mValueText = new TextView(mContext);
mValueText.setGravity(Gravity.CENTER_HORIZONTAL);
mValueText.setTextSize(32);
params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
layout.addView(mValueText, params);
mListView = new ListView(mContext);
mListView.setDivider(getDivider());
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
mAdapter.remove(mAdapter.getItem(position));
}
});
layout.addView(mListView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
return layout;
}
public void setEntries(Set<String> entries)
{
mAdapter.clear();
mAdapter.addAll(entries);
}
@Override
public void showDialog(Bundle state) {
super.showDialog(state);
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mContext);
Set<String> excludedFolders = pref.getStringSet(mContext.getString(R.string.KEY_EXCLUDED_FOLDERS), new HashSet<String>());
mAdapter.clear();
mAdapter.addAll(excludedFolders);
Button positiveButton = ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (mPreferenceKey != null)
{
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(mContext).edit();
Set<String> rows = new HashSet<>();
for (int i = 0; i < mAdapter.getCount(); ++i)
{
rows.add(mAdapter.getItem(i));
}
editor.putStringSet(mPreferenceKey, rows);
editor.apply();
}
((AlertDialog) getDialog()).dismiss();
}
private Drawable getDivider() {
int[] attrs = { android.R.attr.listDivider };
TypedArray a = mContext.obtainStyledAttributes(attrs);
Drawable divider = a.getDrawable(0);
a.recycle();
return divider;
}
}
例如。 header:
<com.anthonymandra.widget.RemovableListPreference
android:key="@string/KEY_EXCLUDED_FOLDERS"
android:negativeButtonText=""
android:title="@string/excludedFolders"
android:summary="@string/excludedSummary"
android:dialogTitle="@string/excludedFolders"
android:dialogMessage="@string/excludedMessage"/>
我有一个文件夹列表,我想在首选项中显示为字符串列表。我正在通过 SharedPreferences.Editor.putStringSet()
存储文件夹。用户可以单击一行以删除该条目。
我不确定如何在自定义中显示这些值 Preference
;一个 ListView 将是理想的。内置首选项不支持此用例,并且 Preference.getPersistedStringSet
已隐藏 "pending API approval",显然已隐藏多年,因此自定义首选项将无法轻松工作。
我可以在自定义 Preference
中使用带有静态辅助方法的分隔字符串来确保对 SharedPreferences.Editor.putString()
(而不是 putStringSet
)的调用格式正确,但这是有点马虎。有更好的想法吗?
下面是保存一组字符串的例子:
SharedPreferences sp = SharedPreferences.getDefaultSharedPreferences(this);
//Save the values
SharedPreferences.Editor editor = sp.edit();
Set<String> set = new HashSet<String>();
set.addAll(listOfFolders);
editor.putStringSet("key", set);
editor.commit();
//Get the values
Set<String> set = sp.getStringSet("key", null);
希望这对你有用。
编辑:
您还可以使用具有一组条目和条目值的 ListPreference。您可以随时以编程方式更改这些条目,例如:
listPref.setEntries(R.array.listArray);
listPref.setEntryValues(R.array.listValues);
您还可以像这样持久化数据:
listPref.setPersistent(true);
更多信息: http://developer.android.com/reference/android/preference/ListPreference.html
所以我创建了一个自定义 DialogPreference
,因为现有视图本来就是 poor/confusing 用户体验。它实际上 link 到(并且需要) StringSet
首选项键并允许用户删除条目。您可以修改 onClick
以使其表现不同。
public class RemovableListPreference extends DialogPreference implements OnClickListener
{
private static final String androidns="http://schemas.android.com/apk/res/android";
private ListView mListView;
private ArrayAdapter<String> mAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1);
private TextView mSplashText,mValueText;
private String mPreferenceKey;
private Context mContext;
private String mDialogMessage;
public RemovableListPreference(Context context, AttributeSet attrs) {
super(context,attrs);
mContext = context;
// Message attribute for the alert dialog
int mDialogMessageId = attrs.getAttributeResourceValue(androidns, "dialogMessage", 0);
if(mDialogMessageId == 0)
mDialogMessage = attrs.getAttributeValue(androidns, "dialogMessage");
else
mDialogMessage = mContext.getString(mDialogMessageId);
// Key attribute for the view, used to automatically update the preferences
int preferenceId = attrs.getAttributeResourceValue(androidns, "key", -1);
if (preferenceId == -1)
throw new RuntimeException(RemovableListPreference.class.getSimpleName() + " requires a preference key (android:key)");
else
mPreferenceKey = mContext.getString(preferenceId);
}
@Override
protected View onCreateDialogView() {
LinearLayout.LayoutParams params;
LinearLayout layout = new LinearLayout(mContext);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(6,6,6,6);
mSplashText = new TextView(mContext);
if (mDialogMessage != null)
mSplashText.setText(mDialogMessage);
layout.addView(mSplashText);
mValueText = new TextView(mContext);
mValueText.setGravity(Gravity.CENTER_HORIZONTAL);
mValueText.setTextSize(32);
params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
layout.addView(mValueText, params);
mListView = new ListView(mContext);
mListView.setDivider(getDivider());
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
mAdapter.remove(mAdapter.getItem(position));
}
});
layout.addView(mListView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
return layout;
}
public void setEntries(Set<String> entries)
{
mAdapter.clear();
mAdapter.addAll(entries);
}
@Override
public void showDialog(Bundle state) {
super.showDialog(state);
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mContext);
Set<String> excludedFolders = pref.getStringSet(mContext.getString(R.string.KEY_EXCLUDED_FOLDERS), new HashSet<String>());
mAdapter.clear();
mAdapter.addAll(excludedFolders);
Button positiveButton = ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (mPreferenceKey != null)
{
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(mContext).edit();
Set<String> rows = new HashSet<>();
for (int i = 0; i < mAdapter.getCount(); ++i)
{
rows.add(mAdapter.getItem(i));
}
editor.putStringSet(mPreferenceKey, rows);
editor.apply();
}
((AlertDialog) getDialog()).dismiss();
}
private Drawable getDivider() {
int[] attrs = { android.R.attr.listDivider };
TypedArray a = mContext.obtainStyledAttributes(attrs);
Drawable divider = a.getDrawable(0);
a.recycle();
return divider;
}
}
例如。 header:
<com.anthonymandra.widget.RemovableListPreference
android:key="@string/KEY_EXCLUDED_FOLDERS"
android:negativeButtonText=""
android:title="@string/excludedFolders"
android:summary="@string/excludedSummary"
android:dialogTitle="@string/excludedFolders"
android:dialogMessage="@string/excludedMessage"/>