Mengubah Bahasa Aplikasi Android dengan Memanfaatkan Assets

Bagikan jika Anda sukai postingan ini!

Aplikasi menampilkan Bahasa Indonesia
Aplikasi menampilkan Bahasa Indonesia

Suatu aplikasi yang ditujukan untuk pengguna seluruh dunia tentunya harus menyiapkan sebuah fitur pengubahan bahasa aplikasi untuk kenyamanan pengguna dengan beranaka ragam bahasa yang digunakan di dunia. Pada pembahasan kali ini kita akan membuat sebuah aplikasi yang dilengkapi dengan menu untuk mengubah bahasa. Hanya 2 (dua) bahasa saja yang akan dicontohkan, yaitu Bahasa Inggris (English) dan Bahasa Indonesia.

Mari kita langsung ke pengembangan. Buat sebuah proyek baru pada Android Studio, pilih Basic Activity sebagai main activty yang akan digunakan. Mari samakan persepsi, nama proyek adalah Language, kemudian nama paket (package) yang akan digunakan adalah com.inochi.language, dan bahasa pemrograman yang digunakan adalah Java.

Konfigurasi proyek Android Language
Konfigurasi proyek Android Language

Setelah lingkungan pengembangan proyek siap, mari kita ubah skrip untuk layout content_main.xml, menjadi seperti di bawah ini.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <FrameLayout
        android:id="@+id/fraMain"
        android:padding="8dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            
            <TableRow
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
                <TextView
                    android:id="@+id/tvwName"
                    android:layout_width="100dp"
                    android:layout_height="wrap_content"
                    android:text="name" />
                <EditText
                    android:id="@+id/editName"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ems="10"
                    android:inputType="textPersonName" />
            </TableRow>
            <TableRow
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
                <TextView
                    android:id="@+id/tvwEmail"
                    android:layout_width="100dp"
                    android:layout_height="wrap_content"
                    android:text="email" />
                <EditText
                    android:id="@+id/editEmail"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ems="10"
                    android:inputType="textEmailAddress" />
            </TableRow>
            <TableRow
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
                <TextView
                    android:id="@+id/tvwAddress"
                    android:layout_width="100dp"
                    android:layout_height="wrap_content"
                    android:text="address" />
                <EditText
                    android:id="@+id/editAddress"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ems="10"
                    android:lines="2"
                    android:gravity="top"
                    android:inputType="textMultiLine" />
            </TableRow>
            <TableRow
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
                <TextView
                    android:id="@+id/tvwBirthDate"
                    android:layout_width="100dp"
                    android:layout_height="wrap_content"
                    android:text="birth_date" />
                <EditText
                    android:id="@+id/editBirthDate"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ems="10"
                    android:lines="2"
                    android:gravity="top"
                    android:inputType="date" />
            </TableRow>
            
        </LinearLayout>
        
    </FrameLayout>
</android.support.constraint.ConstraintLayout>

Berikut ini tampilan desain dari content_main.xml.

Tampilan desain layout content_main.xml
Tampilan desain layout content_main.xml

Selanjutnya kita akan menambahkan assets pada proyek. Lihat panel paling kiri dari lingkungan kerja Android Studio Anda. Klik kanan pada cabang app kemudian sorot menu New, sorot menu Folder, kemudian klik menu Assets Folder.

Menambahkan folder assets
Menambahkan folder assets

Saat ditampilkan dialog New Android Component, langsung klik saja tombol Finish. Sekarang pada panel kiri lingkungan kerja Android Studio, atau disebut panel Project, sudah terdapat cabang baru dengan nama assets.

Cabang assets pada panel Project
Cabang assets pada panel Project

Selanjutnya kita akan menambahkan folder baru di dalam folder assets ini. Klik kanan cabang assets kemudian sorot menu New, dan klik menu Directory. Beri nama folder/direktori baru tersebut dengan nama lang.

Membuat folder lang apada dialog New Directory
Membuat folder lang pada dialog New Directory

Pada folder lang kita akan menambahkan 2 (dua) buah berkas baru untuk keperluan bahasa. Klik kanan pada cabang lang di panel Project kemudian sorot menu New, lalu klik File. Beri nama berkas baru ini dengan nama id.json.

Membuat berkas id.json pada dialog New File
Membuat berkas id.json pada dialog New File

Tambahkan sebuah berkas baru lagi, dan beri nama en.json. Lengkapi konten dari berkas-berkas tersebut menjadi seperti di bawah ini.

id.json

{
  "name":"Nama",
  "email":"Surel",
  "address":"Alamat",
  "birth_date":"Tgl. Lahir"
}

en.json

{
  "name":"Name",
  "email":"Email",
  "address":"Address",
  "birth_date":"Birth Date"
}
Dua buah berkas baru di assets-lang
Dua buah berkas baru di assets-lang

Untuk aplikasi dengan fitur multi bahasa, kita harus membuat pelokalan berkas sumber daya strings.xml sesuai bahasa yang akan ditambahkan pada aplikasi. Bahasa bawaan dari aplikasi Android adalah Bahasa Inggris (English). Karena kita akan menambahkan bahasa baru yaitu Bahasa Indonesia kita perlu untuk menambahkan pelokalan berkas sumber daya strings.xml untuk Bahasa Indonesia.

Cara pembuatannya, klik kanan cabang res pada panel Project, sorot menu New, kemudian klik menu Android Resource File. Pada dialog New Resource File yang ditampilkan, isikan data di bawah ini.

  • File name: strings.xml
  • Directory name: values-in
Menambahkan berkas strings.xml baru
Menambahkan berkas strings.xml baru

Folder values-{kode} pada Directory name adalah folder yang akan digunakan untuk pelokalan bahasa. Untuk pelokalan Bahasa Indonesia, kode pelokalan yang digunakan adalah in.

Sekarang perhatikan pada panel Project. Lihat cabang res->values. Pada cabang strings sekarang mempunyai 2 (dua) anak cabang, yaitu strings.xml dan strings.xml (in).

Dua anak cabang pada strings
Dua anak cabang pada strings

Ubah skrip dari kedua anak cabang strings tersebut menjadi seperti di bawah ini.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Language</string>
    <string name="action_settings">Settings</string>

    <string name="action_en">English</string>
    <string name="action_id">Indonesia</string>

    <string name="name">Name</string>
    <string name="email">Email</string>
    <string name="address">Address</string>
    <string name="birth_date">Birth Date</string>
</resources>

strings.xml (in)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Language</string>
    <string name="action_settings">Pengaturan</string>

    <string name="action_en">English</string>
    <string name="action_id">Indonesia</string>

    <string name="name">Nama</string>
    <string name="email">Surel</string>
    <string name="address">Alamat</string>
    <string name="birth_date">Tgl. Lahir</string>
</resources>

Pada aplikasi nantinya akan terdapat 2 (dua) buah menu dengan judul English dan Indonesia. Mari kita tambahkan kedua menu ini. Pada panel Project, buka berkas menu_main.xml di cabang app->res->menu. Ubah skripnya menjadi seperti di bawah ini.

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.inochi.language.MainActivity">
    <item
        android:id="@+id/action_en"
        android:orderInCategory="100"
        android:title="@string/action_en"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_id"
        android:orderInCategory="100"
        android:title="@string/action_id"
        app:showAsAction="ifRoom" />
</menu>

Berikutnya kita akan menambahkan kelas baru pada paket aplikasi. Perluas cabang java pada panel Project, klik kanan pada cabang com.inochi.language, sorot menu New, kemudian klik Java Class. Beri nama kelas dengan nama ViewItem pada dialog yang ditampilkan.

Membuat kelas baru ViewItem pada paket
Membuat kelas baru ViewItem pada paket

Lengkapi kode sumber kelas ViewItem seperti di bawah ini,

package com.inochi.language;

import android.widget.TextView;

public class ViewItem {
    private int id;
    private String text;
    private TextView textView;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public TextView getTextView() {
        return textView;
    }

    public void setTextView(TextView textView) {
        this.textView = textView;
    }
}

Tambahkan sebuah kelas baru lagi pada com.inochi.language beri nama dengan Language, kemudian lengkapi kode sumbernya seperti di bawah ini.

package com.inochi.language;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.res.AssetManager;

public class Language {
    private String content;
    private Context context;
    private String file;

    public Language(Context context, String file){
        this.context = context;
        this.file = file;
        content = readText();
    }

    public String getTranslate(int id) {
        String translate = "";
        if (file.length() == 0){
            translate = context.getResources().getString(id);
        } else {
            if (content.length() == 0){
                translate = context.getResources().getString(id);
            } else {
                try {
                    String key = context.getResources().getResourceEntryName(id);
                    translate = getTranslations(key);

                    if (translate.length() == 0){
                        translate = context.getResources().getString(id);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return translate;
    }

    public String[] getTranslateArray(int id) {
        String[] translate = null;
        if (file.length() == 0){
            translate = context.getResources().getStringArray(id);
        } else {
            if (content.length() == 0){
                translate = context.getResources().getStringArray(id);
            } else {
                try {
                    String key = context.getResources().getResourceEntryName(id);
                    translate = getArrayTranslations(key);

                    if (translate == null){
                        translate = context.getResources().getStringArray(id);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return translate;
    }

    public String getTranslate(String key) {
        String translate = "";
        if (content.length() > 0){
            try {
                translate = getTranslations(key);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return translate;
    }

    public String[] getTranslateArray(String key) {
        String[] translate = null;
        if (content.length() > 0){
            try {
                translate = getArrayTranslations(key);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return translate;
    }

    private String getTranslations(String key){
        String value = "";

        if (content.length() > 0){
            JSONObject jsonObject;

            try {
                jsonObject = new JSONObject(content);
                value = jsonObject.getString(key);
            } catch (JSONException e) {

                e.printStackTrace();
            }
        }

        return value;
    }

    private String[] getArrayTranslations(String key){
        String[] value = null;

        if (content.length() > 0){
            JSONObject jsonObject;

            try {
                jsonObject = new JSONObject(content);
                JSONArray jsonArray = jsonObject.getJSONArray(key);
                int length = jsonArray.length();

                if (length > 0){
                    List<String> list = new ArrayList<>();
                    for (int i = 0; i < length; i++) {
                        list.add(jsonArray.getString(i));
                    }
                    value = list.toArray(new String[list.size()]);
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        return value;
    }

    /*
    Membaca berkas assets sebagai plain text
    */
    private String readText(){
        AssetManager am = context.getAssets();
        InputStream inputStream;
        StringBuilder result = new StringBuilder();

        if (file.length() > 0){
            try {
                inputStream = am.open("lang/" + file + ".json");
                BufferedReader reader;
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String line = reader.readLine();
                if (line != null)
                    if (line.length() > 0) result.append(line);

                while(line != null){
                    line = reader.readLine();
                    if (line != null)
                        if (line.length() > 0) result.append(line);
                }

                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result.toString();
    }
}

Terakhir, ubah kode sumber kelas MainActivity menjadi seperti di bawah ini.

package com.inochi.language;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private ArrayList<ViewItem> viewItems;
    private Language langEn;
    private Language langId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        langEn = new Language(this, "en");
        langId = new Language(this, "id");

        viewItems = new ArrayList<>();

        ViewGroup viewGroup = findViewById(R.id.fraMain);
        registerTextViews(viewGroup);
    }

    private void registerTextViews(ViewGroup viewGroup){
        int viewChiledCount = viewGroup.getChildCount();
        for (int i = 0; i < viewChiledCount; i++) {
            View child = viewGroup.getChildAt(i);
            if (child instanceof TextView){
                TextView textView = (TextView) child;

                int id = textView.getId();
                String text = textView.getText().toString();

                ViewItem viewItem = new ViewItem();
                viewItem.setId(id);
                viewItem.setText(text);
                viewItem.setTextView(textView);

                viewItems.add(viewItem);
                String translate = langEn.getTranslate(text);

                textView.setText(translate);
            } else if (child instanceof ViewGroup){
                this.registerTextViews((ViewGroup) child);
            }
        }
    }

    private void changeLanguage(String lang){
        if (viewItems != null){
            if (viewItems.size() > 0){
                for (ViewItem viewItem : viewItems){
                    TextView textView = viewItem.getTextView();
                    String text = viewItem.getText();

                    if (lang.equals("id")){
                        textView.setText(langId.getTranslate(text));
                    } else {
                        textView.setText(langEn.getTranslate(text));
                    }
                }
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_en) {
            changeLanguage("en");
        } else if (id == R.id.action_id){
            changeLanguage("id");
        }

        return super.onOptionsItemSelected(item);
    }
}

Beres, sekarang tinggal kita coba jalankan aplikasinya. Cobalah klik menu English, kemudian klik menu Indonesia.

Tampilan aplikasi menampilkan Bahasa Inggris (English)
Tampilan aplikasi menampilkan Bahasa Inggris (English)

Kode sumber aplikasi ini dapat Anda unduh di https://github.com/InochiSoft/Android-Switch-Language.