-2

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.
        }
    }
}
  • Your question is a bit confused. I guess you want to change the app language by selecting it from a Spinner. Now, if this is what you want, what do you get instead? Which is the issue? Could you explain it in clear words, please? – Phantômaxx Dec 25 '14 at 14:24
  • yes. Der sir, i want to change language, and this working fine. but after selecting the language the whole page is reloads as Methods setLocale() does. but after reloading the spinner shows the default Language. or i would say the 0 position. i want to show the Language selected. – Devendra Singh Chouhan Dec 26 '14 at 06:28
  • Well, this is obvious, since the Spinner has been reloaded with the Activity, so it stays at the default position (0), unless you don't tell it to move to another position. This is easily done with a simple instruction like `mySpinner.setSelection(currLang);`. Obvoiusly, you must have an integer (currLang) which represents your current language. – Phantômaxx Dec 26 '14 at 10:02
  • i done, int currLang; and in spinner l2 = mySpinner.getSelectedItem().toString(); if (l2=="German"){ curLang=1; }else if(l2=="English(US)"){ curLang=1; }else if(l2=="French"){ curLang=1; } mySpinner.setSelection(curLang); but not worked. – Devendra Singh Chouhan Dec 26 '14 at 10:40
  • Really? currLang is **always = 1**? That won't work. It will **always** show you `English (US)` – Phantômaxx Dec 26 '14 at 10:42
  • but i get selected in l2 and than check if its German,Eng and French if one of them than i put 1 in that. im not much expert Den sir – Devendra Singh Chouhan Dec 26 '14 at 10:43
  • NO. currLang MUST reflect the selected language. German, currLang = 0. English, currLang = 1. French, currLang = 2. And currLang will be the new index (0, 1 or 2) for the Spinner, at start. Easy. – Phantômaxx Dec 26 '14 at 10:45
  • ok i will do it. but is that ok to take selected item in String like i done in this? or i would say how will i remember which language was selected? thatswhy i taken that selected in l2. – Devendra Singh Chouhan Dec 26 '14 at 10:47
  • NO. **==** won't work for Strings. You have to use I2.equals("Some String"). – Phantômaxx Dec 26 '14 at 10:48
  • now i done this, l2 = mySpinner.getSelectedItem().toString(); if (l2.equals("English(US)")) { curLang = 0; } else if (l2.equals("German")) { curLang = 1; } else if (l2.equals("French")) { curLang = 2; } mySpinner.setSelection(curLang); i written this in onitemselectedlistener's body. would you like to have a look via teamviewer? – Devendra Singh Chouhan Dec 26 '14 at 11:05
  • This: `mySpinner.setSelection(curLang);` should be placed in the `onCreate()` method. You better save the currLang value to SharedPreferences (when the Spinner index changes), so that you can retrieve it in onCreate. – Phantômaxx Dec 26 '14 at 11:10
  • Hello sir, [Please watch this video](https://drive.google.com/file/d/0BxVa3_wqOp_rcEdVNHhzTE0wcWM/view?usp=sharing) I want to create UI same like this. what should i do? please help this time. Thanks. – Devendra Singh May 22 '15 at 13:18

1 Answers1

0

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".

Community
  • 1
  • 1
Dalija Prasnikar
  • 27,212
  • 44
  • 82
  • 159
  • These methods for getting and storing the Language value? if yes. i 'd say i am getting the selected language, but after reloading the activity the spinner doesn't show the selected language. as method "setLocal" does. my problem is how to show the previously selected language with flag in the spinner. – Devendra Singh Chouhan Jan 05 '15 at 08:27
  • I tried your code but its not working correctly. its just showing a blank screen. did i made any error in this? last time please..please help me. – Devendra Singh Chouhan Jan 08 '15 at 07:24
  • OK, your app is probably stuck in loop with `setLocale`. First you have to see what happens if you comment out `setLocale`. If your app starts normally then re-entrancy is issue here. I would then uncomment `setLocale` and add `mySpinner.setOnItemSelectedListener(null);` before `mySpinner.setSelection` that should prevent calling `setLocale` during `onCreate` initialization – Dalija Prasnikar Jan 08 '15 at 11:10
  • I have just noticed that you have gone too far with cleaning your code and you have modified your `MyCustomAdapter` to the point that it is not functional at all. Use your old code for `MyCustomAdapter` that part was working fine. Actually, before you try anything from my previous comment you should fix your adapter. – Dalija Prasnikar Jan 08 '15 at 11:30
  • i followed you but if i do comment setLocal it runs normally. even after giving selection null before mySpinner.setSelection . this time im using old code. – Devendra Singh Chouhan Jan 09 '15 at 07:14
  • I don't understand does it all work correctly now, or do you still have issues with `setLocal`. – Dalija Prasnikar Jan 09 '15 at 09:55
  • I have found out this question and I suggest you read it http://stackoverflow.com/questions/2900023/change-language-programatically-in-android It seems that the way you use `setLocale` in not completely correct. – Dalija Prasnikar Jan 09 '15 at 10:02
  • i meant that if comment setLocal then it runs normally. and after writing mySpinner.setOnItemSelectedlistner(null) plus uncomment setLocal it fails. i will read that answer now. Resources res = this.getResources(); // Change locale settings in the app. DisplayMetrics dm = res.getDisplayMetrics(); android.content.res.Configuration conf = res.getConfiguration(); conf.locale = new Locale(language_code.toLowerCase()); res.updateConfiguration(conf, dm); will it load language w/o reloading page. what is language_code? – Devendra Singh Chouhan Jan 09 '15 at 10:32
  • I have updated code with new `setLocale` and `restartActivity` methods. If `setLocale` method I have used here does not work properly, I suggest that you try code from other answers in Change language programmatically question. – Dalija Prasnikar Jan 09 '15 at 11:36
  • this time restartActivity creating issue.i directly start intent in restartAcitivity w/o if else it keeps blinking. and if i comment it in onItemSelectedListener. works but doesnt change language. – Devendra Singh Chouhan Jan 09 '15 at 12:04
  • Try adding `mySpinner.setOnItemSelectedListener(null)` before `mySpinner.setSelection` – Dalija Prasnikar Jan 09 '15 at 12:06
  • btw im very grateful to you. you are so helpful. will you suggest any other control or way to perform this task in a genuine manner?? wait...plx – Devendra Singh Chouhan Jan 09 '15 at 12:09
  • same situation although. :( – Devendra Singh Chouhan Jan 09 '15 at 12:14
  • Using spinner control is perfectly fine. We just have to prevent it to get into loop, and setting Listener to null should do the trick. What could be more problematic at the end is that you should not be changing language dynamically, because Android is not designed to support that. Using different control will not help. You can make it work with spinner or it will not properly work ever. – Dalija Prasnikar Jan 09 '15 at 12:15
  • What is minimum API level you have to suport? – Dalija Prasnikar Jan 09 '15 at 12:17
  • yes, i understood but my boss wants me to do that. well if its not affecting your work than you can re-create else leave it. minimum API is 13. i changed to 11 but... unsuccessful. – Devendra Singh Chouhan Jan 09 '15 at 12:19
  • very nice. thanks a lot. btw i created a popup something like this i will mail in a while. – Devendra Singh Chouhan Jan 10 '15 at 14:11
  • hi! I'm here. and this time for a counseling question and will not take much time.that is. [Here](http://it-ebooks-api.info/) i wanted to develop an app using this API. i just clueless where from i have to start.. – Devendra Singh Chouhan Jan 15 '15 at 10:30
  • [link] (http://stackoverflow.com/questions/28713771/taking-string-after-a-perticuler-word-in-android) i want if user writes in edittext and if presses @ the searchbox open contacts and if user presses # it will be highlighted and i will store it in database. – Devendra Singh Chouhan Feb 25 '15 at 07:58
  • http://stackoverflow.com/questions/29138883/getting-values-from-sqlite-using-group-by-null-pointer – Devendra Singh Chouhan Mar 19 '15 at 07:14
  • Hello @DalijaPrasnikar I am in trouble please help this time. [VIDEO] (https://drive.google.com/file/d/0BxVa3_wqOp_rcEdVNHhzTE0wcWM/view?usp=sharing) please watch this video, I want to make UI like this app. – Devendra Singh May 22 '15 at 13:20
  • @DevendraSingh Sorry, but I don't have answers to all the questions you might ask. You might try asking questions that do not fit at Stack Overflow at [Android Development](https://plus.google.com/u/0/communities/105153134372062985968) and [Android App Design](https://plus.google.com/u/0/communities/116667001535376136065) G+ communities. – Dalija Prasnikar May 23 '15 at 10:01