ภาพรวม
ตัวอย่างนี้แสดงวิธีเปลี่ยน Theme ของ Activity ขณะรันโปรแกรม โดยใช้ setTheme() **ก่อน** setContentView()
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
Android Studio → File → New Project
ขั้นตอนที่ 2: Layout (res/layout/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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hello World!"
android:textSize="24sp"/>
</RelativeLayout>
ขั้นตอนที่ 3: MainActivity.java (เปลี่ยน Theme ใน onCreate)
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// สำคัญ: ต้องเรียก setTheme() ก่อน super.onCreate() และ setContentView()
setTheme(android.R.style.Theme_Black); // ใช้ System Theme
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
ขั้นตอนที่ 4: Manifest
<?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:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
การทดสอบ
รันแอป - จะแสดง Theme สีดำ (Theme_Black) แทน Theme เริ่มต้น
⚠️ ข้อจำกัดสำคัญ
- ต้องเรียก setTheme() ก่อน super.onCreate() และ setContentView() - เรียกหลังจะไม่มีผล
- เปลี่ยน Theme ได้เฉพาะ Activity นั้นๆ ไม่ใช่ Whole App
- ไม่สามารถเปลี่ยน Theme หลัง setContentView() แล้ว (ต้อง Recreate)
วิธีเปลี่ยน Theme ทั้งแอป (App-wide Theme Change)
ต้อง Recreate Activity ทั้งหมด หรือ Restart App:
1. ใช้ SharedPreferences เก็บ Theme Preference
// ThemeHelper.java
public class ThemeHelper {
private static final String PREF_THEME = "theme_pref";
private static final String KEY_THEME = "theme";
public static void setTheme(Context context, int themeResId) {
context.getSharedPreferences(PREF_THEME, Context.MODE_PRIVATE)
.edit().putInt(KEY_THEME, themeResId).apply();
}
public static int getTheme(Context context) {
return context.getSharedPreferences(PREF_THEME, Context.MODE_PRIVATE)
.getInt(KEY_THEME, R.style.AppTheme);
}
}
// ใน BaseActivity (extends ทุก Activity)
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(ThemeHelper.getTheme(this));
super.onCreate(savedInstanceState);
// ...
}
// เปลี่ยน Theme
ThemeHelper.setTheme(this, R.style.DarkTheme);
recreate(); // หรือ restart App
2. ใช้ AppCompatDelegate (DayNight Mode - API 17+)
// เปลี่ยนโหมด Dark/Light ทั้งแอป AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); // Dark AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); // Light AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); // ตามระบบ // ต้อง Recreate Activity เพื่อ見效果 recreate();
3. Custom Themes (Light/Dark)
<!-- res/values/themes.xml (Light) -->
<style name="Theme.MyApp.Light" parent="Theme.MaterialComponents.DayNight.Light">
<item name="colorPrimary">@color/purple_500</item>
<item name="colorOnPrimary">@color/white</item>
</style>
<!-- res/values-night/themes.xml (Dark) -->
<style name="Theme.MyApp.Dark" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="colorPrimary">@color/purple_200</item>
<item name="colorOnPrimary">@color/black</item>
</style>
System Themes ที่ใช้ได้ทันที
android.R.style.Theme_Black- สีดำandroid.R.style.Theme_Light- สีขาวandroid.R.style.Theme_Holo- Holo (API 11+)android.R.style.Theme_Material- Material (API 21+)Theme.AppCompat.Light.DarkActionBar- AppCompat LightTheme.AppCompat.DayNight.DarkActionBar- DayNight
สรุป
| ความต้องการ | วิธีที่แนะนำ |
|---|---|
| เปลี่ยน Theme Activity เดียวครั้งเดียว | setTheme() ก่อน super.onCreate() |
| ผู้ใช้สลับ Light/Dark ได้ | AppCompatDelegate.setDefaultNightMode() + recreate() |
| Custom Theme หลายแบบ | SharedPreferences + BaseActivity.setTheme() + recreate() |
| ตาม System Setting | Theme.MaterialComponents.DayNight + MODE_NIGHT_FOLLOW_SYSTEM |