【问题标题】:Where to store Android preference keys?在哪里存储 Android 偏好键?
【发布时间】:2010-05-18 12:18:48
【问题描述】:

当我创建偏好活动时,我会在 xml 文件中定义所有偏好。每个首选项都有一个在此 xml 中定义的键。但是当我访问偏好时,我会写:

SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean foo_value = appPreferences.getBoolean("foo_key_defined_in_xml", false);

有没有办法避免以硬编码的方式引用“foo_key_defined_in_xml”? 也许有可能以 R 风格的方式引用它(而不是引用字符串)?

【问题讨论】:

    标签: java android android-preferences


    【解决方案1】:

    我发现可以将键存储在 strings.xml 中并从 preferences.xml 中引用它们,就像所有其他值 android:key="@string/preference_enable" 一样。

    在代码中,您可以通过键入getString(R.string.preference_enable) 来引用密钥

    您可以使用<xliff:g> 标记将字符串标记为不翻译。见Localization Checklist

    <string name="preference_enable"><xliff:g id="preference_key">enable</xliff:g></string>
    

    【讨论】:

    • 这是最好的方法,因为它允许您在一个地方更改密钥,并且它将传播到设置页面以及您在代码中引用它的任何地方。
    • 我不建议这样做,因为当您支持多语言 xml 文件时,密钥字符串也可能会被无意中翻译。
    • 好吧,你应该把这些键保存在一个不同的文件中,这个文件只包含静态值,没有翻译。
    • 哇,我建议阅读官方教程,对于那些仍然对此感到困惑的人developer.android.com/training/basics/data-storage/…
    • @Singgum3b:您建议的链接告诉我们引用常规字符串 ala R.string.my_key。这是有问题的,因为当您发送 strings.xml 文件进行翻译时,您的 key 也会被翻译,从而导致潜在的错误(来自不同版本)。使用&lt;xliff:g&gt; 也不能保证有效;它不会对翻译者隐藏字符串,也不会阻止他们进行更改。所以我们仍然存在本地化问题。叹息。
    【解决方案2】:

    你可以在“res/values”中使用“keys.xml”文件,但应该这样写,这样你在使用多种语言时应该不会有问题:

        <resources
        xmlns:tools="http://schemas.android.com/tools"
        tools:ignore="MissingTranslation">
    
        <string name="key1">key1</string>
        <string name="key2">key2</string>
    ...
    </resources>
    

    然后你可以像 xml 中的普通字符串一样引用它:

    ....
    android:key="@string/key1"
    ....
    

    或在您的 java 代码中,例如:

    SwitchPreference Pref1= (SwitchPreference) getPreferenceScreen().findPreference(getString(R.string.key1));
    

    【讨论】:

    • 我比接受的答案更喜欢它,因为它更干净(实际上在 cmets 中建议了该答案)。唉,“string/”命名空间仍然会被实际的字符串和首选项键污染——必须使用前缀来很好地解决它。
    【解决方案3】:

    在 strings.xml 中将键标记为不可翻译:

    <string name="screw_spacing_key" translatable="false">Screw spacing</string>
    <string name="screw_spacing_title">Screw spacing</string>
    <string name="screw_spacing_summary">Set screw spacing</string>
    

    用法:

    <EditTextPreference
        android:key="@string/screw_spacing_key"
        android:title="@string/screw_spacing_title"
        android:summary="@string/screw_spacing_summary"/>
    

    见:Configure untranslatable rows

    【讨论】:

    • 我认为这是最清楚最合适的答案。是的,我们仍然依靠手工编码的翻译人员来满足这个不翻译的要求,但它是有记录的并且易于理解。此外,许多自动翻译工具会自动识别这一点,根本不会显示不可翻译的字符串。为什么我是第一个对此投票的人,我错过了什么吗?
    【解决方案4】:

    试试getString(R.string.key_defined_in_xml)

    【讨论】:

    • 不起作用。 android:key 中的值不存储在此类中。
    【解决方案5】:

    据我所知,没有更好的方法来引用首选项键(除了可能使用静态最终字符串将字符串存储在类中)。

    SDK 文档中给出的example 与您在示例中给出的相同,

    【讨论】:

    • 我喜欢这样做。这样,当您创建一个新密钥时,在您创建它的同一个文件中,有一个公共静态最终 String 对其的引用,任何可能需要引用它的类都可以使用它。
    【解决方案6】:

    使用帮助类来隐藏 getString() 怎么样 - 在每个活动或服务中实例化一次帮助器。例如:

    class Pref {
    
        final String smsEnable_pref;
        final String interval_pref;
        final String sendTo_pref;
        final String customTemplate_pref;
        final String webUrl_pref;
    
        Pref(Resources res) {       
             smsEnable_pref = res.getString(R.string.smsEnable_pref);
             interval_pref = res.getString(R.string.interval_pref);
             sendTo_pref = res.getString(R.string.sendTo_pref);
             customTemplate_pref = res.getString(R.string.customTemplate_pref);
             webUrl_pref = res.getString(R.string.webUrl_pref);
        }
    }
    

    【讨论】:

    • 我不确定 ddcruver 的含义 即使你在 /res/values/string.xml 中定义了一个资源来保存这个键名,你也不能在 android:key 中使用它="key_name"。 正如 Pixel 所写,您可以执行 android:key="@string/preference_key"。也许我错过了什么。
    【解决方案7】:

    不确定这篇文章是否需要另一个答案,让我这样结束:

    -扩展所有需要的首选项并添加此代码

       final static private int[] ATTR_INDEX = {android.R.attr.id};
        private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes){
            if(attrs == null) return;
            AttributeReader attributes = new AttributeReader().setAttrsIndex(ATTR_INDEX).parse(attrs);
            int id = attributes.asResourceID(0);
            setKey(AppContext.getIdentifierName(id));
        }
    
    • 在xml中,不要使用key属性而是android:id="@+id/...
    • 最后要取回价值,

      SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getContext()); String preference_1 = SP.getString(AppContext.getIdentifierName(R.id.pref_key_1), null);

    这样,您不必创建需要维护的字符串文件,只需动态创建任何 id。但是您需要熟悉扩展视图并阅读 attr 以找到您想要的(这里是 id 属性)

    【讨论】:

      猜你喜欢
      • 2018-01-26
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 2019-08-27
      • 1970-01-01
      • 1970-01-01
      • 2018-03-13
      • 1970-01-01
      相关资源
      最近更新 更多