Multilingual Android app using spinner

爷,独闯天下 提交于 2019-12-23 06:29:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!