1

I'm new to android programming and I would like to do the following: I have a spinner which lets you change language. I have set it up and it works quite well. However the issue is that it does not remember the chosen language (in the spinner). So if you were to close the app and restart it, it will revert to the first item on the spinner which is english. I want to change the function in such a way that once you select an item, it remembers it.

I've set up a shared preference which remembers which language is picked. However I can't make the shared preference the lead since then I could never change the chosen language, and if I make the chosen language the lead then the preference will always follow the chosen language even at the start where the chosen language should actually follow the preference. Here's the code that I have now. I hope anyone can help me we this since I've been breaking my brain over it for a while now

    pref_language = pref.getString("language",  "en");
    //pref_language_begin = pref.getBoolean("language_begin", false);

    final Spinner spinner_languages = (Spinner) findViewById(R.id.spinner_languages);
    spinner_languages.setAdapter(new CustomSpinnerAdapter(MainActivity.this, R.layout.customspinneritem, languages, language_flags));
    spinner_languages.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            parent.getItemAtPosition(position);
            language_chosen = (String) parent.getItemAtPosition(position);
            if (!pref_language.equals(language_chosen)) {
                SetLocale(language_chosen);
                pref_language = language_chosen;
                edit.putString("language", pref_language);
                //edit.putBoolean("language_begin", true);
                edit.apply();
                recreate();
            }
            else{
            }
        }

The customspinneradapter is just there to let me select both a language and a flag for it. I think I might need a second preference but I have no idea on how to implement it. The leading language at start up should be the preference but the language after choosing one in the spinner should be the chosen language. I was thinking about using an onclick listener but I'm not sure I should with spinners.

Surely there must be a more simpler way and I'm just not thinking straight. Hope you guys can help me out!

2 Answers2

0

just use setSelection method for initial selecting item after setting adapter (position must be smaller than list items count, without adapter set spinner have 0 items)

spinner_languages.setSelection(position);

position may be picked e.g. by iterating through languages array (passed to adapter) and comparing each lang to pref_language

int position = -1;
for(int i=0; i < languages.size(); i++) {
    if(pref_language.equals(languages.get(i))){
        position = i;
        break;
    }
}
if (position >=0) { // found
    spinner_languages.setSelection(position);
}

check out THIS topic about spinner selection

snachmsm
  • 17,866
  • 3
  • 32
  • 74
  • Thanks for your answer but I tried this before. It got me into the issue that if I do this, the MainActivity will not be updated because for it to be updated it needs to be recreated and it will not get to that point since the language_chosen is then equal to the pref_language. I can't make an if else about what to do when language_chosen is equal to pref_language because it will always execute since it's an onItemSelected listener and using recreate() there will cause a spam of MainActivities. So this answer by itself won't help me – queen_dragon Jul 27 '21 at 23:20
  • EDIT: I was too hasty. Your answer in combination with the answer of @Andrij solved my issue. your loop goes at the end of my oncreate method so that language_chosen is properly selected. And Andrij pointed out that if I use SetLocale before the super.onCreate the language of the main menu will be changed before it is called so it won't need to be recreated. Thanks you both! – queen_dragon Jul 27 '21 at 23:39
0

I will give you couple suggestions..

  1. Name your variables with the "cammel case" technique. For example: spinner_languages shoud be named spinnerLanguages . Be a pro :)

  2. Make a key for languages in shared preferences as a global and constant variable to use it everywhere in a class or classes and prevent typo mistake (if you don't know what is 'global variable" please google it):

    static final String LANGUAGES_KEY = "languages";

  3. Just when you start your activity ( onCreate() method but before super.onCreate(savedInstanceState); ) read your shared preferences and set language to the app:

    // language from android system

    String langSystem = Locale.getDefault().getLanguage();

    String lang = sharedPreferences.getString(LANGUAGES_KEY, langSystem);

    // update language

    SetLocale(lang);

  4. After that find the right language index for spinner (for example by using for loop) and use: spinnerLanguages.setSelection(languageIndex)

Andrij
  • 218
  • 2
  • 8
  • 1
    You answer solved my issue! I should have used SetLocale before the super.onCreate or possibly before the setContentView. In any case changing the language before the MainActivity is opened/created ensures that the language is changed and you don't need to recreate it. Thanks to you and @snachmsm 's loop for the selection my issue is now actually fixed. – queen_dragon Jul 27 '21 at 23:41