【问题标题】:ListPreference changes being ignored in Kotlin在 Kotlin 中忽略 ListPreference 更改
【发布时间】:2020-02-04 01:58:13
【问题描述】:

为什么我的ListPreference 没有在偏好更改时执行所需的操作?我关注了this video tutorial,但由于某种原因,监听器无法正常工作。我还没有在 Kotlin 中看到任何关于如何做到这一点的工作教程。

root_preferences.xml

<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">

    <ListPreference
        app:defaultValue="reply"
        app:entries="@array/reply_entries"
        app:entryValues="@array/reply_values"
        app:key="list_reply"
        app:title="@string/reply_title"
        app:useSimpleSummaryProvider="true" />

</PreferenceScreen>

arrays.xml

<resources>
    <!-- Reply Preference -->
    <string-array name="reply_entries">
        <item>Reply</item>
        <item>Reply to all</item>
    </string-array>

    <string-array name="reply_values">
        <item>reply</item>
        <item>reply_all</item>
    </string-array>
</resources>

活动

class SettingsActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.settings_activity)
        supportFragmentManager
            .beginTransaction()
            .replace(R.id.settings, SettingsFragment())
            .commit()
        supportActionBar?.setDisplayHomeAsUpEnabled(true)

       val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
       sharedPreferences.registerOnSharedPreferenceChangeListener(this)
    }

    class SettingsFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey)
        }
    }

    override fun onDestroy() {
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
        //...
        super.onDestroy()
    }

    override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
        when (key){
            "reply" -> {
                Toast.makeText(this, "Reply selected", Toast.LENGTH_SHORT).show()
            }

            "reply_to_all" -> {
                Toast.makeText(this, "Reply To All selected", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

【问题讨论】:

  • 你在哪里打电话registerOnSharedPreferenceChangeListener()
  • onCreate 方法中
  • 由于您的ListPreference 键是list_reply,如果您为此添加一个分支到您的when,它会得到控制吗?
  • @CommonsWare 我是在分支中添加when (key) 还是when (something else)

标签: android kotlin android-activity sharedpreferences android-preferences


【解决方案1】:

你有:

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
    when (key){
        "reply" -> {
            Toast.makeText(this, "Reply selected", Toast.LENGTH_SHORT).show()
        }

        "reply_to_all" -> {
            Toast.makeText(this, "Reply To All selected", Toast.LENGTH_SHORT).show()
        }
    }
}

当您的SharedPreferences 中的值发生变化时,这将被调用。 key 是与更改的首选项值关联的键。在屏幕上显示SharedPreferences 的情况下,该密钥来自android:keyapp:key

在您的情况下,您的app:keylist_reply

<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">

    <ListPreference
        app:defaultValue="reply"
        app:entries="@array/reply_entries"
        app:entryValues="@array/reply_values"
        app:key="list_reply"
        app:title="@string/reply_title"
        app:useSimpleSummaryProvider="true" />

</PreferenceScreen>

您的onSharedPreferenceChanged() 函数现在将完全忽略这一点,因为您不是在寻找list_reply。您需要在现有的when 中添加一个分支来覆盖list_reply,例如:

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
    when (key){
        "reply" -> {
            Toast.makeText(this, "Reply selected", Toast.LENGTH_SHORT).show()
        }

        "reply_to_all" -> {
            Toast.makeText(this, "Reply To All selected", Toast.LENGTH_SHORT).show()
        }

        "list_reply" -> {
            Toast.makeText(this, "The user chose something from the ListPreference -- get the updated value from the SharedPreferences", Toast.LENGTH_SHORT).show()
        }
    }
}

而且,如果 replyreply_to_all 不是真正的密钥,您可以执行以下操作:

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
    when (key) {
        "list_reply" -> {
            if (sharedPreferences.getString(key, "reply") == "reply") {
              // TODO
            }
            else {
              // TODO
            }
        }
    }
}

【讨论】:

  • @MacaronLover:““reply”和“reply_to_all”应该在“list_reply”分支内吗? - 大概。您将replyreply_to_all 作为list_reply 首选项的候选值。这些是,而不是。您的when 正在查看密钥。如果您想在用户更改与list_reply 键关联的值时采取特定操作,请将Toast 替换为检索当前list_reply 首选项值并根据它采取一些操作的代码。
  • 如何检查在list_reply 键中选择的值?我了解这些值不是键,所以显然它们不会被执行。
  • @MacaronLover:“我如何检查在 list_reply 键中选择的值?” -- 与您读取任何SharedPreferences 值的方式相同。在您的情况下,请在 SharedPreferences 上调用 getString() 以获取与所需键关联的值。
  • 这是漫长的一天。 onSharedPreferenceChanged 只包含sharedPreferenceskey 所以我需要创建一个新的if 语句来调用getString()吗?
  • @MacaronLover: “我需要创建一个新的 if 语句来调用 getString() 吗?” ——大概。请参阅我的更新答案。 “这是漫长的一天”——吃马卡龙! :-)
【解决方案2】:

replyreply_to_all 不是偏好键。您偏好的密钥是list_reply。你可以使用这样的方式。

       when (key){
            "list_reply" -> {
                val preference = sharedPreferences as? ListPreference
                if(preference?.value.equals("reply")){
                    //Your code
                }else if(preference?.value.equals("reply_all")){
                    //Your code
                }
            }

        }

【讨论】:

  • "reply""reply_all" 首选项值在我选择其中任何一个时都不会被执行。
  • 然后检查使用System.out.println(preference?.value)选择的值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
相关资源
最近更新 更多