DropDownPreference setOnPreferenceChangeListener初始化后会自行调用

时间:2020-05-18 10:04:33

标签: android android-preferences

我已针对此问题提交了a bug here,我认为这是平台错误。如果您有DropDownPreference OnPreferenceChangeListener,则Android似乎会一次“选择”第一个项目,并且只有在首次在新的应用程序上打开屏幕时才会“选择”一次,从而触发侦听器。

有没有人看到这种行为,我该如何预防?我尝试放入一个布尔型优先标记以滤除不触发信号,但是现在下拉菜单中的第一个选项是不可选择的,直到我选择另一个选项为止。我相信在幕后,PreferenceFragmentCompat认为下拉菜单中的第一个选项是“默认”,我尝试在偏好设置上使用setDefaultValuesetValueIndex来尝试以编程方式对其进行初始化无济于事。 xml首选项没有设置默认值。

我的下拉首选项称为“准备时间”,它的初始值来自我们的服务器,然后来自本地数据库:

val setting = settings.getSettingByName(preferencesHelper.merchantBranchID, AppConstants.Settings.PREP_TIME)

    if (setting != null) {
        var prepTime = setting.value
        if (prepTime.isEmpty()) {
            prepTime = "15"
        }

        val summaryProvider = Preference.SummaryProvider<DropDownPreference> {
            if (prepTime.toInt() == 1)
                "$prepTime minute"
            else
                "$prepTime minutes"
        }

        val preference = findPreference<DropDownPreference>(AppConstants.Settings.PREP_TIME)
        withContext(Dispatchers.Main) {
            preference?.summaryProvider = summaryProvider
            preference?.setDefaultValue(setting.value)
        }

        preference?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { pref, newValue ->

            if(prefs.prepTimePreferenceInittedDueToPlatformBug) {
                updateSetting(groupID, branchID, setting.id, newValue.toString())
                        .observe(viewLifecycleOwner, Observer { response ->
                            response?.let {
                                Timber.i("Settings put observed, status= " + response.status + ", data=" + response.data)
                        })

                prepTime = newValue.toString()
            }
            else{
                //We need to do this to prevent a false positive for new installs.
                //Dropdown preferences exhibit this, which I think is a platform bug, reported:
                //https://issuetracker.google.com/issues/156047817
                prefs.prepTimePreferenceInittedDueToPlatformBug = true
            }
            true
        }
    }

1 个答案:

答案 0 :(得分:0)

据我所知,这与Spinners有关。某些情况会在不应该触发的情况下触发它,如果它是this bug,则不会被修复。这个有很多荒谬的技巧。这是我的解决方案,从那里的答案之一扩展而来:

var actualSpinnerClick = false;
preference?.onPreferenceClickListener = Preference.OnPreferenceClickListener {
    actualSpinnerClick = true
    true
}

preference?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { pref, newValue ->
    if(actualSpinnerClick) {
        actualSpinnerClick = false;
        updateSetting(groupID, branchID, setting.id, newValue.toString())
                .observe(viewLifecycleOwner, Observer { response ->
                    response?.let {
                        Timber.i("Settings put observed, status= " + response.status + ", data=" + response.data)
                    }
                })

        prepTime = newValue.toString()
    }
    true
}