ตัวอย่างนี้สาธิตวิธี จัดการการเปลี่ยนทิศทางหน้าจอ (Orientation Change) ใน Android
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่ใน Android Studio
ไปที่ File → New Project และกรอกรายละเอียดที่จำเป็นทั้งหมด
ขั้นตอนที่ 2: เพิ่มโค้ดใน res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView
android:id="@+id/actionEvent"
android:textSize="40sp"
android:layout_marginTop="30dp"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
ใช้ TextView แสดงสถานะ Orientation
ขั้นตอนที่ 3: เพิ่มโค้ดใน src/MainActivity.java
package com.example.myapplication;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView actionEvent;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actionEvent = findViewById(R.id.actionEvent);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
actionEvent.setText("ORIENTATION LANDSCAPE");
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
actionEvent.setText("ORIENTATION PORTRAIT");
}
}
}
ขั้นตอนที่ 4: เพิ่มโค้ดใน AndroidManifest.xml (สำคัญมาก)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<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="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
การทดสอบแอปพลิเคชัน
รันแอปพลิเคชันบนอุปกรณ์ Android จริง ใน Android Studio คลิกไอคอน Run เลือกอุปกรณ์ แล้วตรวจสอบหน้าจอเริ่มต้น

หมุนหน้าจอเป็น Landscape จะแสดงข้อความเปลี่ยน

คำอธิบาย android:configChanges
เมื่อระบุ android:configChanges="orientation|screenSize|keyboardHidden" ใน Manifest:
- Activity จะไม่ถูก Destroy/Recreate เมื่อหมุนหน้าจอ
- แทนที่จะสร้างใหม่ ระบบจะเรียก
onConfigurationChanged()แทน - Developer ต้องจัดการ UI/Resource เองใน onConfigurationChanged
Config Changes ที่รองรับ
| Value | ความหมาย |
|---|---|
orientation |
การหมุนหน้าจอ (Portrait ↔ Landscape) |
screenSize |
ขนาดหน้าจอเปลี่ยน (API 13+ จำเป็นต้องรวมกับ orientation) |
keyboardHidden |
Keyboard แสดง/ซ่อน |
screenLayout |
Layout Direction (LTR/RTL), Screen Size Category |
uiMode |
Mode เปลี่ยน (Desk Dock, Car Dock, Night Mode, Watch) |
locale |
ภาษา/Locale เปลี่ยน |
fontScale |
ขนาดฟอนต์ระบบเปลี่ยน |
density |
Pixel Density เปลี่ยน |
สองวิธีจัดการ Orientation Change
วิธีที่ 1: ให้ระบบ Recreate Activity (Default - ไม่ใส่ configChanges)
- Pros: โค้ดน้อย, UI อัปเดตอัตโนมัติตาม Layout-port/land, Safe
- Cons: ต้อง Save/Restore State (onSaveInstanceState, ViewModel), ช้ากว่าเล็กน้อย
- Best Practice: ใช้ ViewModel + LiveData/Flow เก็บข้อมูล ไม่ต้องมานั่ง Save/Restore เอง
วิธีที่ 2: จัดการเองด้วย configChanges + onConfigurationChanged (ตัวอย่างนี้)
- Pros: ไม่ต้อง Recreate, เร็วกว่า, ควบคุม Transition เองได้
- Cons: ต้องอัปเดต View/Layout เอง, ยากต่อการ Maintain, Bug-prone
- ใช้เมื่อ: Camera, Video Player, Game, Map - ที่ Recreate ทำให้หยุดทำงาน/กระพริบ
แนวทางปฏิบัติที่ดีที่สุด (Modern Best Practice)
💡 แนะนำ: อย่าใช้ configChanges เพื่อหลีกเลี่ยง Recreate
- ใช้ ViewModel เก็บข้อมูล (Survive Configuration Change)
- ใช้ ViewBinding / DataBinding ผูก View อัตโนมัติ
- สร้าง Layout แยก:
layout/activity_main.xml(Port) และlayout-land/activity_main.xml(Land) - ระบบจะ Inflate Layout ใหม่ให้อัตโนมัติเมื่อหมุน - โค้ดสะอาดกว่าและปลอดภัยกว่า
ตัวอย่าง Layout แยก Portrait/Landscape
res/
├── layout/
│ └── activity_main.xml # Portrait (Vertical)
└── layout-land/
└── activity_main.xml # Landscape (Horizontal - 2 Pane, Wider)