SwitchPreference的onChecked/onClick监听器

32

我翻了一晚上的书,但似乎无法完成这个小东西。我想在应用程序的PreferenceActivity中添加一个SwitchPreference,如下图所示。

在说太多之前,我的问题就是:我似乎无法在首选项的Switch部分上放置监听器。我能够在首选项上设置onPreferenceTreeClick和onPreferenceClick,并且如果我按下文本部分,那么可以正常工作。但是当我将开关从关闭状态更改为打开状态时,开关本身没有做任何事情。

我已阅读了SwitchPreference的文档。我还看了看android/packages/Settings,发现AOSP使用的是Switch而不是SwitchPreference来控制Wi-Fi和蓝牙。

以下是我的尝试(如果您按整个首选项项目,则可正常工作,但如果仅按开关,则不起作用):

示例:

public class Preferences extends SherlockPreferenceActivity {

public static final String PREF_THEME = "pref_theme_interface";
public static final String PREF_ROOT = "pref_root";
public static final String PREF_APP = "pref_app";

public static SharedPreferences mTheme;
private static SharedPreferences mUpdate;
public static SharedPreferences.Editor mEditor;

public boolean SDK_COMPAT = true;

boolean pSwitch = false; 
boolean update = true;

Preference autoUpdate;

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            this.finish();
            break;
    }
    return super.onOptionsItemSelected(item);
}

    @Override
protected void onCreate(Bundle savedInstanceState) {
    setTheme(MainActivity.THEME);
    super.onCreate(savedInstanceState);
    final ActionBar actionBar = getSupportActionBar();
    actionBar.setHomeButtonEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setIcon(R.drawable.ic_preferences);

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        SDK_COMPAT = false;
    }

    mUpdate = PreferenceManager.getDefaultSharedPreferences(this);
    update = mUpdate.getBoolean("update", false);

    // Load the preferences from an XML resource
    addPreferencesFromResource(R.xml.preferences);

    setPreferenceScreen(createPreferenceSDK());

}

private PreferenceScreen createPreferenceSDK() {
    // Root
    PreferenceScreen root = (PreferenceScreen)findPreference(PREF_ROOT);

    PreferenceCategory prefApp = (PreferenceCategory)findPreference(PREF_APP);

    //root.addPreference(prefApp);

    if (SDK_COMPAT == true) {
        pSwitch = true;
        autoUpdate = new SwitchPreference(this);
        autoUpdate.setKey("auto_update_pref");
        autoUpdate.setTitle(R.string.auto_update);
        //autoUpdate.setSummary(update == false ? "Disabled" : "Enabled");
        prefApp.addPreference(autoUpdate);
    } else {
        pSwitch = false;
        autoUpdate = new CheckBoxPreference(this);
        autoUpdate.setKey("auto_update_pref");
        autoUpdate.setTitle(R.string.auto_update);
        autoUpdate.setSummary(R.string.auto_update_summary);
        prefApp.addPreference(autoUpdate);
    }

    autoUpdate.setOnPreferenceClickListener(new OnPreferenceClickListener() {

        public boolean onPreferenceClick(Preference preference) {
            mEditor = mUpdate.edit();
            boolean checked = ((SwitchPreference) preference)
                    .isChecked();
            if (checked) {
                update = true;
                mEditor.putBoolean("update", true);
                mEditor.commit();
                autoUpdate.setSummary(update == false ? "Disabled" : "Enabled");
            } else {
                update = false;
                mEditor.putBoolean("update", false);
                mEditor.commit();
                autoUpdate.setSummary(update == false ? "Disabled" : "Enabled");
            }
            return true;
        }

    });

    return root;
}
请再次阐述我的问题,以防我把你弄丢了。如何在SwitchPreference的Switch部分上设置一个监听器?如果这是显而易见的事情,请友善地指出。昨晚我尝试添加这个时已经很晚了。

非常感谢您的提前帮助。

备注: 1. 我不反对使用CheckBoxPreference,但我更喜欢使用Switch因为它看起来更好。

  1. 是的,我知道有一种更简单/更好的方法可以使用res/xml和res/xml-v14添加动态偏好设置,而不是进行SDK检查。我只是为了测试而这样做。

偏好设置屏幕截图

编辑

希望这能帮助其他人!谢谢Tushar的建议:-)

autoUpdate.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

        @Override
        public boolean onPreferenceChange(Preference preference,
                Object newValue) {
            boolean switched = ((SwitchPreference) preference)
                    .isChecked();
            update = !switched;
            mEditor = mUpdate.edit();
            mEditor.putBoolean("update", update);
            mEditor.commit();
            autoUpdate.setSummary(update == false ? "Disabled" : "Enabled");

            return true;
        }

    });

你尝试过使用setOnPreferenceChangeListener吗? - Tushar
Tushar,实际上我还没有尝试过那个。让我试一下。谢谢。 - tommytomatoe
告诉我进展如何,我很好奇。 - Tushar
感谢您的建议。这就是我所做的,看起来工作得很好。不过isChecked()有趣的一面是,它返回了与我预期相反的结果... 我已经使用了这个方法编辑了原始问题。 - tommytomatoe
是的,我认为在界面上切换按钮非常不受欢迎,因为它们很难从快速一瞥中判断(例如:“开启”文本是指已经开启还是可以开启?)。我将提交我的解决方案作为答案,以便其他人可以更容易地找到它。 - Tushar
是的,我同意您关于用户端切换状态可见性的观点。不过我设置了一个摘要,使其易于查看。再次感谢您的建议 :-) 不确定为什么一开始我没有尝试过。 - tommytomatoe
3个回答

36

使用setOnPreferenceChangeListener()替代setOnPreferenceClickListener()


8

工作代码

public static class SettingsFragment extends PreferenceFragment {

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.pref_notification);

            SwitchPreference vibrateSwitch = (SwitchPreference) findPreference("notification_vibrate");

            if (vibrateSwitch != null) {
                vibrateSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                    @Override
                    public boolean onPreferenceChange(Preference arg0, Object isVibrateOnObject) {
                        boolean isVibrateOn = (Boolean) isVibrateOnObject;
                        if (isVibrateOn) {
                            Vibrator v = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
                            v.vibrate(400);
                        }
                        return true;
                    }
                });
            }
        }

}

0

如果你还没有找到一个好的方法来做到这一点,我已经想出了一些方法,不会在点击首选项时创建多个对onPreferenceChange的调用。我在另一个问题中写了它:双功能SwitchPreference


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接