0

I have made radio group where user can select their desire language and app language changes to selected language but i am not able to use the functions (not sure how to!)

What I did?

  1. I've made settingsActivity
  2. I've added radio group
  3. I've wrote setAppLocale function
  4. I've set onRadioButtonClicked to change languages

Code

settingsActivity.java

package com.xxxxxx.xxxxx;

import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceFragmentCompat;

import android.util.DisplayMetrics;
import android.view.View;
import android.widget.RadioButton;

import java.util.Locale;

public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.settings, new SettingsFragment())
                .commit();
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
    }

    public static class SettingsFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey);
        }
    }


    //locale settings
    public void setAppLocale(String localeCode) {
        Resources res = getResources();
        DisplayMetrics dm = res.getDisplayMetrics();
        Configuration conf = res.getConfiguration();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            conf.setLocale(new Locale(localeCode.toLowerCase()));
        } else {
            conf.locale = new Locale(localeCode.toLowerCase());
        }

        res.updateConfiguration(conf, dm);
    }

    // application language switch
    public void onRadioButtonClicked(View view) {
        // Is the button now checked?
        boolean checked = ((RadioButton) view).isChecked();

        // Check which radio button was clicked
        switch(view.getId()) {
            case R.id.radio_indo:
                if (checked)
                    setAppLocale("id");
                    break;
            case R.id.radio_english:
                if (checked)
                    setAppLocale("en");
                    break;
        }
    }

}

settings_activity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/settings">


    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="4sp"
            android:layout_marginRight="4sp"
            android:weightSum="3"
            android:gravity="center"
            android:orientation="horizontal">

        <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

            <RadioGroup
                    android:id="@+id/appLang"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:layout_marginTop="35dp"
                    android:layout_marginEnd="35dp"
                    android:layout_marginRight="35dp"
                    android:layout_marginStart="35dp"
                    android:layout_marginLeft="35dp"
                    android:orientation="horizontal">

                <TextView
                        android:id="@+id/applangtext"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="@string/applangtextstring" />

                <RadioButton
                        android:id="@+id/radio_indo"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:onClick="onRadioButtonClicked"
                        android:text="@string/indoLang" />

                <RadioButton
                        android:id="@+id/radio_english"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:onClick="onRadioButtonClicked"
                        android:text="@string/englishLang" />

            </RadioGroup>
        </LinearLayout>

    </LinearLayout>
</RelativeLayout>

Question

I need to make 2 things happen in my java file:

  1. Mark current language radio input as selected
  2. Make changes when user select another radio button

The question is how do I connect onRadioButtonClicked to setAppLocale? as well as return current language onCreate in order to show current language selected?

Update

Based on answer below here is my latest update and extra files that I've added. Yet my language switch doesn't work

settingsActivity.java

import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceFragmentCompat;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import java.util.Locale;

public class SettingsActivity extends AppCompatActivity {

    PrefManager prefManager; //added
    RadioButton radio_indo, radio_english; //added
    RadioGroup appLang; //added

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);

        //added
        prefManager = new PrefManager(this);

        radio_indo = findViewById(R.id.radio_indo);
        radio_english = findViewById(R.id.radio_english);
        appLang = findViewById(R.id.appLang);

        if (prefManager.getLanguage().equals("en")) {
            radio_english.setChecked(true);
        } else {
            radio_english.setChecked(true);
        }

        // application language switch (added)
        appLang.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int checkId) {
                switch (checkId) {
                    case R.id.radio_indo:
                        prefManager.setLanguage("id");
                        // you need to restart or recreate your activity after locale change
                        break;
                    case R.id.radio_english:
                        prefManager.setLanguage("en");
                        // you need to restart or recreate your activity after locale change
                        break;
                }
            }
        });

    }

    public static class SettingsFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey);
        }
    }


    //locale settings
    public void setAppLocale(String localeCode) {
        Resources res = getResources();
        DisplayMetrics dm = res.getDisplayMetrics();
        Configuration conf = res.getConfiguration();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            conf.setLocale(new Locale(localeCode.toLowerCase()));
        } else {
            conf.locale = new Locale(localeCode.toLowerCase());
        }

        res.updateConfiguration(conf, dm);
    }

     // removed my old function as new function added to onCreate

}

PrefManager.java added class

import android.content.Context;
import android.content.SharedPreferences;

public class PrefManager {
    private SharedPreferences.Editor editor;
    private Context mContext;
    private SharedPreferences prefs;
    private final String LANGUAGE = "language";
    private final String PREF = "user_data";

    public PrefManager(Context mContext) {
        this.mContext = mContext;
    }

    public String getLanguage() {
        this.prefs = this.mContext.getSharedPreferences(PREF, 0);
        return this.prefs.getString(LANGUAGE, "en");
    }

    public void setLanguage(String language) {
        this.editor = this.mContext.getSharedPreferences(PREF, 0).edit();
        this.editor.putString(LANGUAGE, language);
        this.editor.apply();
    }
}

BaseActivity.java added class

import android.content.Context;

import androidx.appcompat.app.AppCompatActivity;
import java.util.Locale;

/**
 * Created by nilesh on 20/3/18.
 */

public class BaseActivity extends AppCompatActivity {

    @Override
    protected void attachBaseContext(Context newBase) {

        Locale newLocale;

        String lang = new PrefManager(newBase).getLanguage();

        if (lang.equals("en")) {
            newLocale = new Locale("en");
        } else {
            newLocale = new Locale(lang);
        }


        Context context = ContextWrapper.wrap(newBase, newLocale);
        super.attachBaseContext(context);
    }
}

settings_activity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/settings">


    <RadioGroup
            android:id="@+id/appLang"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="35dp"
            android:layout_marginLeft="35dp"
            android:layout_marginTop="90dp"
            android:layout_marginEnd="35dp"
            android:layout_marginRight="35dp"
            android:gravity="center"
            android:orientation="horizontal">

        <TextView
                android:id="@+id/applangtext"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/applangtextstring" />

        <RadioButton
                android:id="@+id/radio_indo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/indoLang" />

        <RadioButton
                android:id="@+id/radio_english"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/englishLang" />

    </RadioGroup>
</RelativeLayout>

This is all I have regarding to language switch.

PS-1: based on provided solution in answer comments I should have add BaseActivity as extends in all my activites but as all my activities are kotlin not java (except settingsActivity) I was not able to add it.

PS-2: even if not getting translatations is because I couldn't add extends at very least I should be able to see translations in my settingsActivity which is java right?

Any idea why this switch doesn't work?

mafortis
  • 6,750
  • 23
  • 130
  • 288

1 Answers1

1

NOTE

You can download source code from github repo

Mark current language radio input as selected

Then you need to save your locale change flag/state inside SharedPreferences

SAMPLE CODE follow these steps

Create one class name PrefManager

import android.content.Context;
import android.content.SharedPreferences;

public class PrefManager {
    private SharedPreferences.Editor editor;
    private Context mContext;
    private SharedPreferences prefs;
    private final String LANGUAGE = "language";
    private final String PREF = "user_data";

    public PrefManager(Context mContext) {
        this.mContext = mContext;
    }

    public String getLanguage() {
        this.prefs = this.mContext.getSharedPreferences(PREF, 0);
        return this.prefs.getString(LANGUAGE, "en");
    }

    public void setLanguage(String language) {
        this.editor = this.mContext.getSharedPreferences(PREF, 0).edit();
        this.editor.putString(LANGUAGE, language);
        this.editor.apply();
    }
}

Now add below code/ condition in your settingsActivity.java

public class JavaActivity extends AppCompatActivity {

    PrefManager prefManager;
    RadioButton radio_indo, radio_english;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_java);
        prefManager = new PrefManager(this);
        radio_indo = findViewById(R.id.radio_indo);
        radio_english = findViewById(R.id.radio_english);

        if (prefManager.getLanguage().equals("en")) {
            radio_english.setChecked(true);
        } else {
            radio_english.setChecked(true);
        }
    }

}

Make changes when user select another radio button

  • When the user changes the language you need to update it SharedPreferences
  • You need to restart or recreate your activity after locale change

Note : you should use RadioGroup.OnCheckedChangeListener() instead of android:onClick="onRadioButtonClicked"

SAMPLE CODE

public class JavaActivity extends AppCompatActivity {

    PrefManager prefManager;
    RadioButton radio_indo, radio_english;
    RadioGroup appLang;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_java);
        prefManager = new PrefManager(this);

        radio_indo = findViewById(R.id.radio_indo);
        radio_english = findViewById(R.id.radio_english);
        appLang = findViewById(R.id.appLang);

        if (prefManager.getLanguage().equals("en")) {
            radio_english.setChecked(true);
        } else {
            radio_english.setChecked(true);
        }

        appLang.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int checkId) {
                switch (checkId) {
                    case R.id.radio_indo:
                        prefManager.setLanguage("id");
                        // you need to restart or recreate your activity after locale change
                        break;
                    case R.id.radio_english:
                        prefManager.setLanguage("en");
                        // you need to restart or recreate your activity after locale change
                        break;
                }
            }
        });
    }

}

Please follow this my previous answer to change locale runtime

https://stackoverflow.com/a/52270630/7666442

AskNilesh
  • 67,701
  • 16
  • 123
  • 163
  • Hi, thanks for the answer but i have very silly question as this is my first attempt with android studio, where should i create this `Create one class name PrefManager` and what option should i chose from `new -> ?` :) SORRY :D – mafortis Sep 26 '19 at 05:25
  • 2
    @mafortis it's ok no problem please check this [How To Create New Java Class in Android Studio](https://abhiandroid.com/androidstudio/how-to-create-new-java-class-in-android-studio) – AskNilesh Sep 26 '19 at 05:27
  • hi :) , sorry but i didn't get this part `Note : you should use RadioGroup.OnCheckedChangeListener() instead of android:onClick="onRadioButtonClicked"` where should i use `RadioGroup.OnCheckedChangeListener()` in my xml? – mafortis Sep 26 '19 at 05:41
  • @mafortis whenever you use `RadioGroup` you should use `OnCheckedChangeListener()` to get selected `radioButton` check this [How to set OnClickListener on a RadioButton in Android?](https://stackoverflow.com/q/8323778/7666442) – AskNilesh Sep 26 '19 at 05:43
  • and as you added `appLang.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {` in `onCreate()` should i remove `public void onRadioButtonClicked(View view)` now? – mafortis Sep 26 '19 at 05:44
  • @mafortis Remove it from`onCreate()` and also from `XML` – AskNilesh Sep 26 '19 at 05:44
  • i did all you said now i get current locale selected in my view but nothing translates when i select other language. – mafortis Sep 26 '19 at 11:20
  • @mafortis after select you need to restart your activity, BTW witch langue your using and have you create two separate `string.xml` files? – AskNilesh Sep 26 '19 at 11:22
  • my settings is java but my other activities are kotlin, yes i have two string files every time i add new string i provide translation of that as well – mafortis Sep 26 '19 at 11:24
  • @mafortis have you checked this answer: https://stackoverflow.com/a/52270630/7666442 – AskNilesh Sep 26 '19 at 11:24
  • @mafortis which two languages you are using in your app? – AskNilesh Sep 26 '19 at 11:26
  • yes i created new class based on your answer there however i wasn't able to use extends in kotlin activities, but at least it should translate my settings activity which is java right? ps: how do i reset my activities after selecting new lang? – mafortis Sep 26 '19 at 11:27
  • @mafortis `how do i reset my activities after selecting new lang?` you need to restart that activity or try to restart app – AskNilesh Sep 26 '19 at 11:30
  • @mafortis find [my contact info from here](https://stackoverflow.com/users/7666442/nilesh-rathod?tab=profile) I will send you demo project tonight – AskNilesh Sep 26 '19 at 11:31
  • Hi, I didn't get your respond on FB but I updated my question would you please check it? – mafortis Sep 27 '19 at 02:05
  • @mafortis sorry for late replay i was little busy, i will provide you sample code soon – AskNilesh Sep 27 '19 at 04:23
  • @mafortis [You can download source code from github repo](https://github.com/RathodNilesh14/LocaleChange) – AskNilesh Sep 27 '19 at 11:02
  • Hi, thanks for sharing that but i wasn't able to see `java/kt` files in order to see classes and functions there is just `xml` files. how should i compare to see if my code is right? – mafortis Sep 28 '19 at 12:11
  • ok found them and trying to make changes as your code however when i use Base class instead of appcomponent() all my activities are become red in other word I can't build my app due to this error. another thing was i was using api 14 your code requires api 17 now I'm downloading api 17 hopefully this solves issue of base extends – mafortis Sep 28 '19 at 12:47
  • 1
    hi, it is working perfectly, i wished to have radio group instead of buttons but it's fine as well. thank you so much. – mafortis Sep 28 '19 at 13:59
  • hi man, after very long time I've got issue with your solution :) the solution works just fine if i use debug app but after uploading app on google store and downloading it from there the localization won't work. it selects new language but doesn't get translations. any idea? i have read some people says google store will config apps based on devices languages and ignores users settings there must be some additional codes to avoid this google store setups – mafortis Oct 18 '19 at 07:58