使用StringSet的自定义首选项

时间:2015-08-18 19:31:32

标签: android sharedpreferences android-preferences

我有一个我想在首选项中显示的文件夹列表作为字符串列表。我通过SharedPreferences.Editor.putStringSet()存储文件夹。用户可以单击一行以删除该条目。

我不确定如何在自定义Preference中显示值; ListView是理想的。内置首选项不支持此用例,Preference.getPersistedStringSet隐藏“待审批API”,显然多年,因此自定义首选项无法轻松运行。

我可以在自定义Preference中使用带有静态帮助方法的分隔字符串,以确保对SharedPreferences.Editor.putString()(而不是putStringSet)的调用格式正确,但这有点草率。有更好的想法吗?

2 个答案:

答案 0 :(得分:1)

所以我创建了一个自定义DialogPreference,因为现有的视图会是一个糟糕/混乱的用户体验。它实际上将链接到(并要求)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;
    }
}

实施例。头:

<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"/>

答案 1 :(得分:0)

以下是保存一组字符串的示例:

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