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

วิธีจัดการการเปลี่ยนทิศทางหน้าจอ (Orientation Change) ใน Android

ตัวอย่างนี้สาธิตวิธี จัดการการเปลี่ยนทิศทางหน้าจอ (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 เลือกอุปกรณ์ แล้วตรวจสอบหน้าจอเริ่มต้น

วิธีจัดการการเปลี่ยนทิศทางหน้าจอ (Orientation Change) ใน Android

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

วิธีจัดการการเปลี่ยนทิศทางหน้าจอ (Orientation Change) ใน Android

คำอธิบาย 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)