问题
I wanted to make multilingual this app,it works fine but issue is it reloads the page to change selected language, after reloading it doesn't showing the selected lang in spinner but changes language in views. Question is how can i set the selected language after reloading or updating lang.also i want to take this selected lang in further activities to load contents in selected lang. Thanks. sorry for any error i made in posting as im new.please ignore the spinner in actionbar.
package com.ssoft.myapp;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Locale;
public class Login extends ActionBarActivity implements ActionBar.OnNavigationListener {
Locale myLocale;
String lan;
String[] Country_list = {"English(US)", "German", "French"};
Integer[] flags = {R.drawable.ic_us, R.drawable.ic_ger, R.drawable.ic_frn};
public TextView frgt;
Button login;
EditText et_UserName = null, et_Password = null;
String String_Email = "", String_Password;
String email_Pattern = "[a-zA-Z0-9._]+@[a-z]+\\.+[a-z]+";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
final Spinner mySpinner = (Spinner) findViewById(R.id.spinner);
mySpinner.setAdapter(new MyCustomAdapter(Login.this,
R.layout.language, Country_list, flags));
mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
lan = mySpinner.getSelectedItem().toString();
Log.e("Language Selected", lan);
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0);
SharedPreferences.Editor editor = pref.edit();
editor.putString("lan", "lan");
/*if (i==0) {
setLocale("en");
}
else*/
if (i == 1) {
setLocale("de");
} else if (i == 2) {
setLocale("fr");
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
frgt = (TextView) findViewById(R.id.forgot);
et_UserName = (EditText) findViewById(R.id.et_UserName);
et_Password = (EditText) findViewById(R.id.et_Password);
login = (Button) findViewById(R.id.btn_Login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String_Email = et_UserName.getText().toString();
String_Password = et_Password.getText().toString();
if (TextUtils.isEmpty(String_Email) || TextUtils.isEmpty(String_Password)) {
if (TextUtils.isEmpty(String_Email))
et_UserName.setError("Please enter email");
if (TextUtils.isEmpty(String_Password))
et_Password.setError("Please enter password");
} else if (!String_Password.matches("[a-zA-Z0-9.?]*")) {
et_Password.setError("special character not allowed");
} else if (!String_Email.matches(email_Pattern)) {
et_UserName.setError("Please enter a valid email");
} else {
Intent i1 = new Intent(Login.this, MainActivity.class);
startActivity(i1);
}
}
});
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
final String[] dropdownValues = getResources().getStringArray(
R.array.languages);
ArrayAdapter adapter = new ArrayAdapter(
actionBar.getThemedContext(),
android.R.layout.simple_spinner_item, android.R.id.text1,
dropdownValues);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
actionBar.setListNavigationCallbacks(adapter, this);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.newheader));
}
@Override
public boolean onNavigationItemSelected(int i, long l) {
/*if (i==0) {
setLocale("en");
Log.d("Selected item is","English");
}
else*/
if (i == 1) {
setLocale("de");
} else if (i == 2) {
setLocale("fr");
}
return true;
}
public void setLocale(String lang) {
myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(this, Login.class);
}
public class MyCustomAdapter extends ArrayAdapter<String> {
public MyCustomAdapter(Context context, int textViewResourceId,
String[] objects, Integer[] image) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
}
@Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
return getCustomView(position, convertView, parent);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return getCustomView(position, convertView, parent);
}
public View getCustomView(int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
// return super.getView(position, convertView, parent);
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.language, parent, false);
TextView label = (TextView) row.findViewById(R.id.country);
label.setText(Country_list[position]);
ImageView icon = (ImageView) row.findViewById(R.id.icon);
icon.setImageResource(flags[position]);
return row;
}
}
public class MyOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
Toast.makeText(
parent.getContext(),
"The country is "
+ parent.getItemAtPosition(pos).toString(),
Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
}
}
回答1:
From what I can gather in your code, you have issue with storing and restoring language. Following two methods will help you do that. After you load language, you can initialize spinner (or any other view).
public void saveLanguage(String language)
{
SharedPreferences pref = getApplicationContext()
.getSharedPreferences("MyPref", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString("lan", language);
editor.commit();
}
public String loadLanguage(String defaultLanguage)
{
SharedPreferences pref = getApplicationContext()
.getSharedPreferences("MyPref", Context.MODE_PRIVATE);
return pref.getString("lan", defaultLanguage);
}
You have to call loadLanguage
in onCreate
, and saveLanguage
when language is changed, before you recreate your activity. You should set defaultLanguage
parameter to whatever language you load by default, so if preferences have not yet been saved loadLanguage
will return default value.
Based on Change language programmatically in Android setting locale should be done onCreate
in every Activity you have to make it work. Also setLocale
should just refresh locale configuration and not restart Activity. Restarting Activity should be done only when user selects different language.
Your setLocale
and restartActivity
methods would be:
public void setLocale(String lang) {
myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
}
public void restartActivity() {
if (Build.VERSION.SDK_INT >= 11) {
recreate();
}
else {
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
overridePendingTransition(0, 0);
startActivity(intent);
overridePendingTransition(0, 0);
}
}
To make it easier to load and save values to spinner you should define Locale_list
in addition to Country_list
List<String> Locale_list = new ArrayList<String>(Arrays.asList("en", "de", "fr"));
And code in onCreate
would look like:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String lan = loadLanguage("en");
setLocale(lan);
setContentView(R.layout.login);
Spinner mySpinner = (Spinner) findViewById(R.id.spinner);
mySpinner.setAdapter(new MyCustomAdapter(this, R.layout.language, Country_list));
mySpinner.setSelection(Locale_list.indexOf(lan));
mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l)
{
String lan = Locale_list.get(i);
saveLanguage(lan);
restartActivity();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
I can see that you are saving language, but you are not loading it anywhere. Also you have obvious bug when you call editor.putString("lan", "lan");
it should be editor.putString("lan", lan);
because your code is not storing value of variable lan
, but string "lan"
.
来源:https://stackoverflow.com/questions/27644863/multilingual-android-app-using-spinner