Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีเปลี่ยนภาษาแอปเมื่อผู้ใช้เลือกภาษาใน Android

ภาพรวม

ตัวอย่างนี้สาธิตการเปลี่ยนภาษาแอปพลิเคชัน (Locale) แบบไดนามิกเมื่อผู้ใช้เลือกจาก Spinner โดยใช้ Configuration และ Resources แล้ว Recreate Activity

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

Android Studio → File → New Project → Empty Activity

ขั้นตอนที่ 2: สร้าง String Resources สำหรับแต่ละภาษา

res/values/strings.xml (Default - English)

<resources>
    <string name="app_name">Language Demo</string>
    <string name="thank_you">Thank you</string>
    <string name="select_language">Select Language</string>
</resources>

res/values-th/strings.xml (Thai)

<resources>
    <string name="app_name">สาธิตภาษา</string>
    <string name="thank_you">ขอบคุณ</string>
    <string name="select_language">เลือกภาษา</string>
</resources>

res/values-es/strings.xml (Spanish)

<resources>
    <string name="app_name">Demo de Idioma</string>
    <string name="thank_you">Gracias</string>
    <string name="select_language">Seleccionar Idioma</string>
</resources>

res/values-fr/strings.xml (French)

<resources>
    <string name="app_name">Démo de Langue</string>
    <string name="thank_you">Merci</string>
    <string name="select_language">Sélectionner la langue</string>
</resources>

res/values-hi/strings.xml (Hindi)

<resources>
    <string name="app_name">भाषा डेमो</string>
    <string name="thank_you">धन्यवाद</string>
    <string name="select_language">भाषा चुनें</string>
</resources>

ขั้นตอนที่ 3: จัดรูปแบบหน้าจอ (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <Spinner
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/spinner"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="32dp"
        android:text="@string/thank_you"
        android:textSize="24sp"
        android:textStyle="bold" />

</RelativeLayout>

ขั้นตอนที่ 4: เขียนโค้ด MainActivity.java

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {

    private Spinner spinner;
    private TextView textView;
    private String currentLanguage = "en";

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

        // โหลดภาษาที่บันทึกไว้ (จาก SharedPreferences)
        loadSavedLocale();

        spinner = findViewById(R.id.spinner);
        textView = findViewById(R.id.textView);

        // รายการภาษา
        List languages = new ArrayList<>();
        languages.add(getString(R.string.select_language));
        languages.add("English");
        languages.add("Español");
        languages.add("Français");
        languages.add("ไทย");
        languages.add("हिन्दी");

        ArrayAdapter adapter = new ArrayAdapter<>(
            this, android.R.layout.simple_spinner_item, languages);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);

        // ตั้งค่า Selection ให้ตรงกับภาษาปัจจุบัน
        setSpinnerSelection();

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView parent, View view, int position, long id) {
                if (position == 0) return; // "Select Language" placeholder
                
                String localeCode;
                switch (position) {
                    case 1: localeCode = "en"; break;
                    case 2: localeCode = "es"; break;
                    case 3: localeCode = "fr"; break;
                    case 4: localeCode = "th"; break;
                    case 5: localeCode = "hi"; break;
                    default: return;
                }
                
                if (!localeCode.equals(currentLanguage)) {
                    setLocale(localeCode);
                } else {
                    Toast.makeText(MainActivity.this, "Language already selected", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onNothingSelected(AdapterView parent) {}
        });
    }

    private void loadSavedLocale() {
        // อ่านจาก SharedPreferences (ควรทำใน Application Class หรือ BaseActivity)
        // ตัวอย่างง่ายๆ:
        currentLanguage = getSharedPreferences("settings", MODE_PRIVATE)
            .getString("locale", "en");
    }

    private void saveLocale(String localeCode) {
        getSharedPreferences("settings", MODE_PRIVATE)
            .edit().putString("locale", localeCode).apply();
    }

    private void setSpinnerSelection() {
        switch (currentLanguage) {
            case "en": spinner.setSelection(1); break;
            case "es": spinner.setSelection(2); break;
            case "fr": spinner.setSelection(3); break;
            case "th": spinner.setSelection(4); break;
            case "hi": spinner.setSelection(5); break;
        }
    }

    private void setLocale(String localeCode) {
        Locale locale = new Locale(localeCode);
        Locale.setDefault(locale);
        
        Resources res = getResources();
        DisplayMetrics dm = res.getDisplayMetrics();
        Configuration conf = res.getConfiguration();
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            conf.setLocale(locale);
        } else {
            conf.locale = locale;
        }
        
        res.updateConfiguration(conf, dm);
        
        // บันทึกภาษาที่เลือก
        saveLocale(localeCode);
        
        // Restart Activity เพื่อโหลด Resource ใหม่
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish();
    }

    @Override
    public void onBackPressed() {
        // ออกจากแอปโดยไม่เก็บใน Back Stack
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
    }
}

ขั้นตอนที่ 5: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name=".MainActivity"
            android:configChanges="locale|layoutDirection">
            <intent-filter>
                
                
            </intent-filter>
        </activity>

    </application>
</manifest>

💡 android:configChanges="locale|layoutDirection"

เพิ่มบรรทัดนี้ใน Activity เพื่อป้องกัน Recreation อัตโนมัติเมื่อ Locale เปลี่ยน (เราจัดการเองใน setLocale)

การทดสอบ

รันแอป → เลือกภาษาจาก Spinner → แอปจะ Restart และแสดงภาษาใหม่ทันที

วิธีเปลี่ยนภาษาแอปเมื่อผู้ใช้เลือกภาษาใน Android วิธีเปลี่ยนภาษาแอปเมื่อผู้ใช้เลือกภาษาใน Android

แนวทางปัจจุบัน: AppCompatDelegate (Support Library)

ใช้ AppCompatDelegate.setApplicationLocales() (API 33+ / AppCompat 1.6+) ซึ่งจัดการทุกอย่างให้อัตโนมัติ:

// build.gradle
implementation "androidx.appcompat:appcompat:1.6.1"

// ใน Application Class หรือ Activity
import androidx.appcompat.app.AppCompatDelegate;
import android.os.LocaleListCompat;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // โหลดภาษาที่บันทึกไว้ตอนเริ่มแอป
        String savedLocale = getSharedPreferences("settings", MODE_PRIVATE)
            .getString("locale", "en");
        setAppLocale(savedLocale);
    }
    
    public static void setAppLocale(String localeCode) {
        LocaleListCompat locales = LocaleListCompat.forLanguageTags(localeCode);
        AppCompatDelegate.setApplicationLocales(locales);
    }
}

// เรียกใช้จาก Activity
MyApplication.setAppLocale("th"); // ไม่ต้อง Restart Activity!

Best Practices

  • เก็บ Locale ใน SharedPreferences หรือ DataStore
  • ตั้งค่า Locale ใน Application.onCreate() ก่อน Activity ใดๆ ทำงาน
  • ใช้ android:configChanges="locale|layoutDirection" ป้องกัน Recreate ซ้ำ
  • ทดสอบ RTL Languages (Arabic, Hebrew) ด้วย layoutDirection
  • แยก String Resources ตามภาษาอย่างเคร่งครัด (อย่า Hardcode String ในโค้ด)