[英]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. 当我单击微调器时,我只能得到该语言的原始值,即: English
或French
但是我需要的是获得该语言的键名,这里是“ 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_code
和R.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.