简体   繁体   English

从微调器值获取strings.xml中的字符串名称属性

[英]Get the string name attribute in the strings.xml from a spinner value

I have a spinner (like a comboBox) in my android app that selects the language you want to change, so the spinner displays only 3 languages from an array according to the current locale of the phone : 我的Android应用程序中有一个微调器(如comboBox),它可以选择要更改的语言,因此微调器根据手机的当前语言环境从数组中仅显示3种语言:

<string-array name="spinner_lang">
    <item>@string/lang_en</item>
    <item>@string/lang_fr</item>
    <item>@string/lang_jp</item>
</string-array>

Here is all of my strings.xml ressources files : http://i.stack.imgur.com/u667T.png 这是我所有的strings.xml资源文件: http : //i.stack.imgur.com/u667T.png

And when I click on my spinner, I can only get the raw value of the language, ie : English or French but what I need is getting the key name of the language, here it's " lang_en " or " lang_fr " because if I can't check this, I have to check nine times instead of 3, and if I want to change the value of the language, I have to change it to both spots. 当我单击微调器时,我只能得到该语言的原始值,即: EnglishFrench但是我需要的是获得该语言的键名,这里是“ lang_en ”或“ lang_fr ”,因为如果可以无需检查,我必须检查9次而不是3次,如果我想更改语言的值,则必须将其更改为两个位置。

I did a lot of research with the keywords "get name of a string value xml" and "how to get the locale of a string" and I found nothing, maybe it wasn't the good keywords. 我对关键字“获取字符串值xml的名称”和“如何获取字符串的语言环境”进行了很多研究,但没有发现任何结果,也许不是很好的关键字。 All I need is getting a string that I can convert to a Locale with forLanguageTag(String languageTag) to give in parameter to my function public void changeLanguage(Locale l) , so I can change the app locale with my spinner. 我需要的是获取一个字符串,该字符串可以使用forLanguageTag(String languageTag)转换为语言环境,以将参数提供给我的函数public void changeLanguage(Locale l) ,以便可以使用微调器更改应用程序语言环境。

I'm running with Android Studio 1.3.2 on Windows 10. 我正在Windows 10上使用Android Studio 1.3.2运行。

I really hope some people will help me ^^ 我真的希望有人能帮助我^^

You are going to need a custom SpinnerAdapter . 您将需要一个自定义的SpinnerAdapter

First, let's establish our XML. 首先,让我们建立XML。

We'll use the string array only to define the order of the language list. 我们将仅使用字符串数组来定义语言列表的顺序 We'll also define the correct language codes here. 我们还将在此处定义正确的语言代码。

In /res/values/strings.xml (ie not locale-specific): /res/values/strings.xml (即,不是特定于语言环境的):

<string-array name="spinner_lang">
    <item>en</item>
    <item>es</item>
    <item>fr</item>
</string-array>

<string-array name="spinner_lang_code">
    <item>code_en</item>
    <item>code_es</item>
    <item>code_fr</item>
</string-array>

<string name="code_en">en-US</string>
<string name="code_es">es-ES</string>
<string name="code_fr">fr-FR</string>

Now in your locale-specific string.xml files, we'll define the language names . 现在,在您特定于语言环境的string.xml文件中,我们将定义语言名称

For example, in /res/values-en/strings.xml 例如,在/res/values-en/strings.xml

<string name="en">English</string>
<string name="es">Spanish</string>
<string name="fr">French</string>

Let's make a simple (inner) class to hold our language data: 让我们做一个简单的(内部)类来保存我们的语言数据:

public static class Lang {
    String mCode;
    String mName;

    public Lang(String code, String name) {
        this.mCode = code;
        this.mName = name;
    }
}

Now we should have everything to code our adapter: 现在我们应该拥有一切来编写适配器代码:

public static class LanguageSelectionAdapter extends BaseAdapter {

    private Lang[] mLangs;

    public LanguageSelectionAdapter(Context context) {

        Resources resources = context.getResources();

        String[] codes = resources.getStringArray(R.id.spinner_lang_code);
        String[] names = resources.getStringArray(R.id.spinner_lang);

        mLangs = new Lang[names.length];
        for (int i = 0; i < names.length; i++) {
            int codeRes = resources.getIdentifier(codes[i], "string", null);
            String code = resources.getString(codeRes);
            int nameRes = resources.getIdentifier(names[i], "string", null);
            String name = resources.getString(nameRes);
            mLangs[i] = new Lang(code, name);
        }
    }

    @Override
    public int getCount() {
        return mLangs == null ? 0 : mLangs.length;
    }

    @Override
    public Object getItem(int position) {
        return mLangs == null ? null : mLangs[position];
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
        }

        TextView text1 = (TextView) convertView.findViewById(android.R.id.text1);
        text1.setText(mLangs[position].mName);

        return convertView;
    }
}

Now when someone selects an item from the Spinner , you need to get the language code based on the language name they selected: 现在,当有人从Spinner选择一个项目时,您需要根据他们选择的语言名称获取语言代码:

spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        LanguageSelectionAdapter adapter = (LanguageSelectionAdapter) parent.getAdapter();
        Lang lang = (Lang) adapter.getItem(position);
        String langCode = lang.mCode;
        Locale locale = Locale.forLanguageTag(langCode);

        // ... switch your Locale here
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }
});

Well, I tried to use your code into my app, It wasn't working so I re-created another project, I used your code but there was some errors : 好吧,我试图在您的应用程序中使用您的代码,该代码无法正常工作,因此我重新创建了另一个项目,我使用了您的代码,但是有一些错误:

I had an error message on setOnItemSelectedListener that was "Cannot resolve symbol 'setOnItemSelectedListener'", so I added a implements AdapterView.OnItemSelectedListener after the class name and I removed spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() . 我在setOnItemSelectedListener上收到一条错误消息“无法解析符号'setOnItemSelectedListener'”,因此在类名之后添加了一个implements AdapterView.OnItemSelectedListener ,并删除了spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()

The String[] codes = resources.getStringArray(R.id.spinner_lang_code); String[] codes = resources.getStringArray(R.id.spinner_lang_code); and the same for the String[] names weren't working, so I replaced it with R.array.spinner_lang_code and R.array.spinner_lang . 以及String[] names的相同性无效,因此我将其替换为R.array.spinner_lang_codeR.array.spinner_lang

I also added the values you mentioned in the /res/values/strings.xml and /res/values-en/strings.xml . 我还添加了您在/res/values/strings.xml/res/values-en/strings.xml提到的值。

I tried to fix these errors, but the following code (without any errors according to android studio) was crashing my app at launch : 我试图修复这些错误,但是以下代码(根据android studio而言没有任何错误)在启动时崩溃了我的应用程序:

package com.example.nicolas.labo1;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Spinner;
import android.widget.TextView;

import java.util.Locale;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener{
    Spinner spinner;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        spinner = (Spinner) findViewById(R.id.spinner);

        ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.spinner_lang, android.R.layout.simple_spinner_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onResume(){
        super.onResume();
        changeLanguage();
    }

    public void changeLanguage(){
        Locale loc = new Locale(Locale.getDefault().toString());
        Configuration config = getBaseContext().getResources().getConfiguration();
        Configuration conf = new Configuration(config);
        conf.locale = loc;
        getBaseContext().getResources().updateConfiguration(conf, getBaseContext().getResources().getDisplayMetrics());
    }

    public void changeLanguage(Locale l){
        Locale loc = new Locale(l.toString());
        Configuration config = getBaseContext().getResources().getConfiguration();
        Configuration conf = new Configuration(config);
        conf.locale = loc;
        getBaseContext().getResources().updateConfiguration(conf, getBaseContext().getResources().getDisplayMetrics());
    }

    public static class Lang {
        String mCode;
        String mName;

        public Lang(String code, String name) {
            this.mCode = code;
            this.mName = name;
        }
    }

    public static class LanguageSelectionAdapter extends BaseAdapter {

        private Lang[] mLangs;

        public LanguageSelectionAdapter(Context context) {

            Resources resources = context.getResources();

            String[] codes = resources.getStringArray(R.array.spinner_lang_code);
            String[] names = resources.getStringArray(R.array.spinner_lang);

            mLangs = new Lang[names.length];
            for (int i = 0; i < names.length; i++) {
                int codeRes = resources.getIdentifier(codes[i], "string", null);
                String code = resources.getString(codeRes);
                int nameRes = resources.getIdentifier(names[i], "string", null);
                String name = resources.getString(nameRes);
                mLangs[i] = new Lang(code, name);
            }
        }

        @Override
        public int getCount() {
            return mLangs == null ? 0 : mLangs.length;
        }

        @Override
        public Object getItem(int position) {
            return mLangs == null ? null : mLangs[position];
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
            }

            TextView text1 = (TextView) convertView.findViewById(android.R.id.text1);
            text1.setText(mLangs[position].mName);

            return convertView;
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        LanguageSelectionAdapter adapter = (LanguageSelectionAdapter) parent.getAdapter();
        Lang lang = (Lang) adapter.getItem(position);
        String langCode = lang.mCode;
        Locale locale = Locale.forLanguageTag(langCode);

        changeLanguage(locale);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }
}

But it's my first time with android and java, I had the first lesson Friday at school, so I'm not really at ease with some things that you can consider as "basics", so I'm sorry if I do some huge mistakes ^^ 但这是我第一次使用android和java,星期五在学校上了第一堂课,所以我对某些可以视为“基础知识”的事情并不放心,所以如果我犯了一些大错误,对不起^^

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM