Programming     Travel Logs     Life Is Good     Surfing Online     About Me
Understand that ethical wealth creation is possible. If you secretly despise wealth, it will elude you.
-Naval Ravikant
2018-07-17 17:44:35

Copy this link when reproducing:
http://www.casperlee.com/en/y/blog/198

I believe that supporting for multiple languages is a necessary function of any Android application, so I'm gonna do this in my application now. Just like before, let's take it easy and enjoy a few beautiful photos first. The artist in the following photos is still Angel Wong.

/Images/20171001/01.jpg

/Images/20171001/02.jpg

/Images/20171001/03.jpg

/Images/20171001/04.jpg

/Images/20171001/05.jpg

/Images/20171001/06.jpg

To support for multiple languages in Android application, it involves the following steps:

  • Add resource files for each specified language
  • Add modules which allow user to change the current language of the application
  • Change the language when user starts the application

 

Add resource files for each specified language

1. Right click on the item "app -> res" in the Project view, a menu will be popped up:

/Images/20171001/101.jpg

2. Select "New -> Android resource file" from the menu, another dialog will be popped up:

/Images/20171001/102.jpg

3. Type in "string.xml" as the file name, select "Locale" in the left box, and click on ">>" to move it to the right box, the dialog will change:

/Images/20171001/103.jpg

4. select "zh: Chinese" in the "Language" box, select "Any Region" from the "Specific Region Only" box, and click "OK" to continue. A new file "string.xml (zh)" will be created and shown under the item "values" in Android Studio:

/Images/20171001/104.jpg

5. Its actual structure on the disk is shown as below:

/Images/20171001/105.jpg

6. Open the default file "strings.xml", we can see that there is an item named "app_name". Change its value to:

<string name="app_name">Personal Expense Book</string>

7. Open the file "string.xml (zh)" which was created, put the following text in:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">个人消费记录本</string>
</resources>

8. Done.

 

Add modules which allow user to change the current language of the application

1. Add a main menu to the application.

    I. Right click on the item "app -> res" in the Project view, select "New -> Directory" from the popped menu, a dialog will be popped up:

/Images/20171001/106.jpg

    II. Type in "menu", and click "OK" to continue, Android Studio will create a folder named "menu" in the "res" folder.

    III. Right click on the item "app -> res -> menu" in the Project view, select "New -> Menu resource file" from the popped menu, a dialog will be popped up:

/Images/20171001/107.jpg

    IV. Type in "main.xml" as the file name, and click "OK" to continue, Android Studio will create the file.

    V. Open the file, and put the following text in to define 2 menu items:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@+id/miSettings" android:title="@string/mi_settings_title"/>
  <item android:id="@+id/miAbout" android:title="@string/mi_about_title"/>
</menu>

    VI. Open the file "app -> res -> values -> strings.xml", and add 2 strings into it:

<resources>
    ...
    <string name="mi_settings_title">Settings</string>
    <string name="mi_about_title">About</string>
</resources>

    VII. Open the file "app -> res -> values -> string.xml (zh)", and add 2 strings into it:

...
    <string name="mi_settings_title">设置</string>
    <string name="mi_about_title">关于</string>
</resources>

    VIII. Override related functions in the main activity:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

            case R.id.miSettings:
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, SettingsActivity.class);
                this.startActivity(intent);
                break;

            case R.id.miAbout:
                Toast.makeText(this, "About", Toast.LENGTH_SHORT).show();
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    IX: Done.

 

2. Add an activity which allows user to change the current language of the application.

    I. Right click on the item "app -> java -> com.casperlee.personalexpense", select "New -> Activity -> Empty activity" from the popped menu, a dialog will be popped up:

/Images/20171001/108.jpg

    II. Type in "SettingsActivity" as the activity name, leave other options to the default, and click "Finish" to create a new activity.

    III. When creating the activity, Android Studio also created the layout file "activity_settings.xml" which is used by "SettingsActivity". Open the file "activity_settings.xml" in the project view, and put the following text in:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_settings"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FF000000"
    android:gravity="center_horizontal"
    tools:context="com.casperlee.personalexpense.SettingsActivity">

    <LinearLayout
        android:id="@+id/layout0"
        android:orientation="horizontal"
        android:paddingTop="8dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <Button
            android:id="@+id/btn_apply"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:text="@string/btn_apply_caption" />
        <Button
            android:id="@+id/btn_cancel"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:text="@string/btn_cancel_caption" />

    </LinearLayout>
    <LinearLayout
        android:id="@+id/layout1"
        android:orientation="horizontal"
        android:paddingTop="8dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/layout0">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:text="@string/text_language_caption"
            android:gravity="right"
            android:layout_gravity="center"
            android:paddingRight="@dimen/activity_horizontal_margin"
            android:textColor="@color/colorWhite" />
        <LinearLayout
            android:id="@+id/layout_language"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_weight="1.0">
            <RadioGroup
                android:id="@+id/rg_languages"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                <RadioButton
                    android:id="@+id/rb_english"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="English"
                    android:textColor="@color/colorWhite" />
                <RadioButton
                    android:id="@+id/rb_chinese"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="中文"
                    android:textColor="@color/colorWhite" />
                <RadioButton
                    android:id="@+id/rb_default"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/rb_default_caption"
                    android:textColor="@color/colorWhite" />
            </RadioGroup>
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

    IV. Open the file "app -> res -> values -> colors.xml" in the project view, add a color into it:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    ...
    <color name="colorWhite">#FFFFFF</color>
</resources>

    V. Open the file "app -> res -> values -> strings.xml", and add several strings into it:

<resources>
    ...
    <string name="btn_apply_caption">Apply</string>
    <string name="btn_cancel_caption">Cancel</string>
    <string name="text_language_caption">Language</string>
    <string name="rb_default_caption">Default</string>
</resources>

    VI. Open the file "app -> res -> values -> string.xml (zh)", and add several strings into it:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    ...
    <string name="btn_apply_caption">应用</string>
    <string name="btn_cancel_caption">取消</string>
    <string name="text_language_caption">语言</string>
    <string name="rb_default_caption">默认</string>
</resources>

    VII. Open the file "app -> java -> com.casperlee.personalexpense -> SettingsActivity", and put the following code in:

package com.casperlee.personalexpense;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;

import com.casperlee.personalexpense.bll.AppParamBll;

public class SettingsActivity extends AppCompatActivity {

    private Layout ui;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
        this.ui = new Layout();
        this.initSettings();
        this.setListeners();
    }

    private void initSettings() {

        switch (AppParamBll.getInstance().getAppLanguage()) {

            case 0:
                this.ui.rgLanguages.check(R.id.rb_english);
                break;
            case 1:
                this.ui.rgLanguages.check(R.id.rb_chinese);
                break;
            default:
                this.ui.rgLanguages.check(R.id.rb_default);
                break;
        }
    }

    private void setListeners() {

        OnMyClickListener listener = new OnMyClickListener();
        this.ui.btnApply.setOnClickListener(listener);
        this.ui.btnCancel.setOnClickListener(listener);
    }

    private void performApplyButtonClick() throws Exception {

        int language = 0;
        switch (this.ui.rgLanguages.getCheckedRadioButtonId()) {

            case R.id.rb_english:
                language = 0;
                break;
            case R.id.rb_chinese:
                language = 1;
                break;
            default:
                language = 2;
                break;
        }

        AppParamBll.getInstance().setAppLanguage(language);
        this.finish();
    }

    private void performCancelButtonClick() {

        this.finish();
    }

    private class Layout {

        private Button btnApply;
        private Button btnCancel;
        private RadioGroup rgLanguages;
        private RadioButton rbEnglish;
        private RadioButton rbChinese;
        private RadioButton rbDefault;

        public Layout() {

            this.initialize();
        }

        private void initialize() {

            this.btnApply = (Button) findViewById(R.id.btn_apply);
            this.btnCancel = (Button) findViewById(R.id.btn_cancel);
            this.rgLanguages = (RadioGroup) findViewById(R.id.rg_languages);
            this.rbEnglish = (RadioButton) findViewById(R.id.rb_english);
            this.rbChinese = (RadioButton) findViewById(R.id.rb_chinese);
            this.rbDefault = (RadioButton) findViewById(R.id.rb_default);
        }
    }

    private class OnMyClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {

            try {
                if (v == SettingsActivity.this.ui.btnApply) {

                    SettingsActivity.this.performApplyButtonClick();

                } else if (v == SettingsActivity.this.ui.btnCancel) {

                    SettingsActivity.this.performCancelButtonClick();
                }
            }
            catch (Exception e) {

                Toast.makeText(SettingsActivity.this, e.getMessage(), Toast.LENGTH_LONG);
            }
        }
    }
}

    VIII. Open the file "app -> java -> com.casperlee.personalexpense -> bll -> AppParamBll", and add a few functions:

...
    private static final String Language = "Language";
    ...
    public int getAppLanguage() {

        String paramValue = this.dal.GetParamValue(Language, "2");
        int result = Integer.parseInt(paramValue);
        if (result < 0 || result > 2) {

            result = 2;
        }

        return result;
    }
    public void setAppLanguage(int aLanguage) throws Exception {

        if (aLanguage < 0 || aLanguage > 2) {

            throw new Exception("The parameter is invalid!");
        }

        String paramValue = Integer.toString(aLanguage);

        if (!this.dal.UpdateParam(Language, paramValue)) {

            this.dal.AddParam(Language, paramValue);
        }
    }

    IX: Done.

 

Change the language when user starts the application

1. Open the file "app -> java -> com.casperlee.personalexpense -> MainActivity", add the following code into it:

...
import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    ...
    private void setLanguage(int aLanguage) {

        Resources r = this.getResources();
        final Configuration c = r.getConfiguration();
        DisplayMetrics dm = r.getDisplayMetrics();
        switch (aLanguage) {

            case 0:
                c.locale = Locale.ENGLISH;
                break;
            case 1:
                c.locale = Locale.CHINESE;
                break;
            default:
                c.locale = Locale.getDefault();
                break;
        }
        r.updateConfiguration(c, dm);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
         this.setLanguage(AppParamBll.getInstance().getAppLanguage());
        this.setTitle(R.string.app_name);
    }

2. Open the file "app -> manifests -> AndroidManifest.xml", and add the following text into it:

<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />

    <application
        ...
        android:configChanges="locale"
...

3. Done!