在Android中使用列表偏好设置

31

我有一个文字转语音应用程序,用户可以选择语言和男声或女声。问题是每种语言都有不同的字符串用于称呼男声和女声,但在我的偏好设置中,我只有两个选项(男声和女声)。

<string-array name="Language">
    <item>English (US)</item>
    <item>English (UK)</item>
    <item>French (France)</item>
    <item>Spanish (Spain)</item>
    <item>Italian</item>
</string-array>

<string-array name="languageAlias">
    <item>"en-US"</item>
    <item>"en-GB"</item>
    <item>"fr-FR"</item>
    <item>"es-ES"</item>
    <item>"it-IT"</item>
</string-array>

<string-array name="Voice">
    <item>Male</item>
    <item>Female</item>
</string-array>

<string-array name="VoiceAlias">
    <item>"usenglishmale"</item>
    <item>"usenglishfemale"</item>
    <item>"ukenglishmale"</item>
    <item>"ukenglishfemale"</item>
    <item>"eurfrenchmale"</item>
    <item>"eurfrenchfemale"</item>
    <item>"eurspanishmale"</item>
    <item>"eurspanishfemale"</item>
    <item>"euritalianmale"</item>
    <item>"euritalianfemale"</item>        
</string-array>

我正在尝试找到一种方法,根据所选语言只引用相关的男性和女性voiceAlias。这里是否可能实现,还是我必须编写一些代码来根据所选语言更改voiceAlias数组的值?

提前感谢。

3个回答

60

好的,您可以通过两个ListPreference和每个偏好设置更改监听器OnPreferenceChangeListener来实现这一点。首先是XML代码:

<ListPreference 
    android:key="language_preference"
    android:title="Language"
    android:entries="@array/Language"
    android:entryValues="@array/languageAlias"/>

<ListPreference 
    android:key="gender_preference"
    android:title="Gender"
    android:entries="@array/Voice"
    android:entryValues="@array/VoiceData"/>

让我们在res/values/array.xml中创建一个新条目:

<string-array name="VoiceData">
    <item>0</item>
    <item>1</item>
</string-array>

现在,在您的PreferenceActivity扩展中,我们将获取在您的SharedPreferences中持久存在的字符串值,并从这些值创建一个全新的条目,该条目的值来自“VoiceAlias”的SharedPreferences

SharedPreferences shareprefs = getPreferenceManager().getSharedPreferences();
Resources resources = YourContext.getResources();

private void makeVoiceData() {
    String languageData = shareprefs.getString("language_preference", "en-US");
    int genderData = Integer.parseInt(shareprefs.getString("gender_preference", "0"));
    String[] voiceAlias = resources.getStringArray(R.array.VoiceAlias);

    int a = 0
    String[] languageAlias = resources.getStringArray(R.array.languageAlias);
    for (a ; a < languageAlias.length ; a++) {
        if (languageAlias[a].equals(languageData)) {
            break;
        }
    }

    shareprefs.putString("VoiceAlias", voiceAlias[(2 * a) + genderData]);
}

ListPreference language_preference = getPreference("language_preference");
ListPreference gender_preference = getPreference("gender_preference");

language_preference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
    public boolean onPreferenceChanged(Preference preference, Object newValue) {
        shareprefs.putString("language_preference", (String) newValue);
        makeVoiceData();
    }
});

gender_preference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
    public boolean onPreferenceChanged(Preference preference, Object newValue) {
        shareprefs.putString("gender_preference", (String) newValue);
        makeVoiceData();
    }
});

谢谢,我喜欢这种方法。但是这行代码是做什么的? voiceAlias[(2 * a) + genderData] - Amanni
变量a在for循环中定义,它代表languageData在languageAlias中的索引。循环遍历languageAlias直到找到languageData的值。a的值乘以2,因为voiceAlias中的声音是成对存在的。genderData被加入其中。如果用户选择男性,则添加0并选择语言对的第一个选项。如果选择女性,则添加1。 - gobernador
1
在仔细查看文档后,似乎ListPreference想要持久化一个字符串。如果您发现是这种情况,请只需使用Integer.parseInt(shareprefs.getString...)包装genderData的声明。 - gobernador
3
getPreference()是什么? - Mark B
请注意,SharedPreferences 在编辑时需要调用 edit()commit()apply() - Jeff Lockhart

10

字符串数组可以使用字符串资源。这是翻译用户值最简单(也可能是最简单)的方法。

<string-array name="user_values">
    <item>@string/value_1</item>
    <item>@string/value_2</item>
</string-array>

请见Working with Strings and String Arrays


-1

很抱歉,我目前无法对答案进行评论,因此我会开一个新的回答。

找到特定项在 String 数组中的索引,不需要编写自己的算法,只需依赖标准 API(通常更快、设计更好,代码也更短):

final int a = Arrays.binarySearch(languageAlias, languageData);

它与以下内容相同:

int a = 0

for (a ; a < languageAlias.length ; a++) {
    if (languageAlias[a].equals(languageData) {
        break;
    }
}

2
以下不是二分查找。@gobernador,不会的。 - Linxy

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