ว่าด้วยเรื่อง Screen Orientation บนแอนดรอยด์
ด้วยความที่แอนดรอยด์เป็นระบบปฏิบัติการณ์ที่สามารถนำไปใช้งานกับอุปกรณ์ได้หลากหลายรูปแบบ จึงมีโอกาสที่อุปกรณ์แอนดรอยด์จะถูกใช้งานได้หลากหลายทิศทาง และนั่นก็ทำให้แอนดรอยด์มีคำสั่งที่เกี่ยวกับ Screen Orientation หรือทิศทางของหน้าจออุปกรณ์ เพื่อให้นักพัฒนากำหนดได้ว่าจะให้แอปรองรับทิศทางของหน้าจอในรูปแบบใดบ้าง
ฟีเจอร์ที่เกี่ยวกับ Screen Orientation สำหรับผู้ใช้
Device's Natural Screen Orientation
อุปกรณ์แอนดรอยด์ทุกตัวจะมีสิ่งที่เรียกว่า Natural Screen Orientation หรือก็คือค่า Default Screen Orientation สำหรับอุปกรณ์แอนดรอยด์แต่ละตัว ซึ่งจะขึ้นอยู่กับว่าเป็น Form Factor แบบไหนและขึ้นอยู่ค่าใน Firmware ที่ผู้ผลิตอุปกรณ์ได้กำหนดไว้
ยกตัวอย่างเช่น Form Factor แบบ Phone จะมี Default เป็น Portrait (แนวตั้ง) และสามารถหมุนเป็น Landscape (แนวนอน) ได้ ในขณะที่ Tablet จะมี Default เป็น Landscape (แนวนอน) และสามารถหมุนเป็น Portrait (แนวตั้ง) เป็นต้น
โดยที่อุปกรณ์แอนดรอยด์ส่วนใหญ่จะรองรับ Screen Orientation ทุกทิศทางอยู่แล้ว แต่ถ้าอิงจากตัวเครื่องก็อาจจะได้แค่บางทิศทางเท่านั้น เช่น Phone จะไม่สามารถหมุนจอเป็น Reverse Portrait (แนวตั้งแบบกลับหัว) ได้ แต่สามารถสั่งผ่านคำสั่งในแอปได้
Orientation ทั้ง 4 ด้านของ Portrait และ Landscape
ถึงแม้ว่าเราจะเรียกรวม ๆ กันว่าเป็น Portrait หรือ Landscape แต่เราก็สามารถแยกย่อยทิศทางในแต่ละด้านแบบเจาะจงได้เช่นกัน โดยจะแบ่งเป็น
- Portrait
- Landscape
- Reverse Portrait
- Reverse Landscape
อย่าลืมว่า Default Orientation, Reverse Portrait และ Reverse Landscape จะแตกต่างไปตามแต่ละ Form Factor
Auto Screen Rotation
เพื่อความสะดวกของผู้ใช้ ระบบแอนดรอยด์จะมี Settings ที่เรียกว่า Auto-rorate (Auto Screen Rotation) เพื่อกำหนดว่าจะให้หน้าจอหมุนตามทิศทางการถือเครื่องโดยอัตโนมัติหรือไม่
ดังนั้นผู้ใช้อาจจะเปิด Auto-rotate หรือปิดอยู่ก็ได้ และการกำหนดค่าดังกล่าวก็จะมีผลกับการกำหนดค่า Screen Orientation ที่อยู่ในแอปด้วยเช่นกัน
Rotate Suggestion Button
บน Android 9 Pie เป็นต้นมา ต่อให้ไม่ได้เปิด Auto-rotate ก็ตาม ถ้าแอปไหนรองรับการหมุนหน้าจอ และอุปกรณ์แอนดรอยด์อยู่ในทิศทางที่หมุนหน้าจอได้ ระบบแอนดรอยด์จะแสดงปุ่มหมุนจอให้ที่ข้างล่างขวามือของหน้าจอ
การกำหนด Screen Orientation ในแอป
นักพัฒนาสามารถกำหนดค่า Screen Orientation ผ่าน Android Manifest โดยกำหนด android:screenOrientation
ไว้ใน <activity>
แบบนี้
<!-- AndroidManifest.xml -->
<manifest ...>
<application ...>
<activity
android:screenOrientation="userPortrait"
... />
</application>
</manifest>
android:screenOrientation
จะกำหนดแยกแต่ละ Activity ดังนั้นถ้ามีการกำหนด Screen Orientation ในแอป ก็อย่าลืมกำหนดทุก Activity ให้ครบ ไม่เช่นนั้นระบบแอนดรอยด์จะมองว่าไม่ได้กำหนดค่าไว้แล้วอิงจาก Screen Orientation ของเครื่องแทน
Screen Orientation บนแอนดรอยด์มีแบบไหนบ้าง
เพื่อให้อุปกรณ์แอนดรอยด์รองรับการใช้งานแอปในทิศทางตามที่นักพัฒนาต้องการ บ้างก็รองรับแค่ทิศทางเดียว บ้างก็รองรับแบบมีเงื่อนไขในรูปแบบที่แตกต่างกันออกไป จึงทำให้ระบบแอนดรอยด์ออกแบบการกำหนดค่าสำหรับ Screen Orientation ดังนี้
unspecified
- เป็นค่า Default ในกรณีที่ไม่ได้กำหนดค่าใด ๆ ไว้ โดยระบบแอนดรอยด์จะเลือก Orientation ให้เหมาะสมกับเครื่องนั้น ๆ ซึ่งอาจจะได้ผลลัพธ์ที่แตกต่างกันออกไปในแต่ละเครื่องbehind
- กำหนดตาม Activity ที่เปิดเมื่อก่อนหน้า (ตัวล่าสุดใน Activity Back Stack)landscape
- กำหนดเป็น Landscape (ไม่รวม Reverse Landscape)portrait
- กำหนดเป็น Portrait (ไม่รวม Reverse Portrait)reverseLandscape
- กำหนดเป็น Reverse Landscape (ไม่รวม Landscape)reversePortrait
- กำหนดเป็น Reverse Portrait (ไม่รวม Portrait)sensorLandscape
- กำหนดเป็น Landscape หรือ Reverse Landscape โดยอ้างอิงจากเซ็นเซอร์ของตัวเครื่อง (ผู้ใช้สามารถหมุนตัวเครื่องเพื่อสลับไปเป็น Landscape อีกฝั่งได้)sensorPortrait
- กำหนดเป็น Portrait หรือ Reverse Portrait โดยอ้างอิงจากเซ็นเซอร์ของตัวเครื่อง (ผู้ใช้สามารถหมุนตัวเครื่องเพื่อสลับไปเป็น Portrait อีกฝั่งได้)userLandscape
- คล้ายกับsensorLandscape
แต่จะอิงจากการตั้งค่าของผู้ใช้ด้วยuserPortrait
- คล้ายกับsensorPortrait
แต่จะอิงจากการตั้งค่าของผู้ใช้ด้วย และใน Form Factor อย่าง Phone จะไม่สามารถทำ Reverse Portrait ในขณะที่ทำบน Tablet ได้sensor
- กำหนดให้ Orientation อิงตามเซ็นเซอร์ของตัวเครื่อง ซึ่งอาจจะไม่ได้รองรับทั้ง 4 ด้าน เพราะขึ้นอยู่กับแต่ละอุปกรณ์fullSensor
- คล้ายกับsensor
แต่จะบังคับให้อุปกรณ์รองรับ Orientation ทั้ง 4 ด้าน ดังนั้นเมื่อใช้บน Phone จะทำให้รองรับ Reverse Portrait ได้ด้วยnosensor
- กำหนดให้ไม่หมุนตามเซ็นเซอร์ของตัวเครื่อง จะอิง Orientation ณ ตอนนั้นของตัวเครื่องแทนuser
- อ้างอิงตาม Preferred Orientation ที่ผู้ใช้กำหนดไว้ใน Setting ของเครื่องfullUser
- โดยปกติจะทำงานแบบเดียวกับfullSensor
แต่ถ้าผู้ใช้ตั้งค่าให้ล็อคการหมุนหน้าจอใน Setting ของเครื่อง ก็จะทำงานแบบเดียวกับuser
locked
- อ้างอิงจาก Orientation ณ ตอนนั้นของตัวเครื่อง และล็อคการหมุนหน้าจอ
ถึงแม้ว่าจะมีค่าให้กำหนดสำหรับ Screen Orientation ได้หลายแบบ แต่ในปัจจุบันเราจะใช้งานกันอยู่แค่ไม่กี่ตัวเท่านั้น เพราะบางตัวก็ถูกสร้างขึ้นมาตั้งแต่สมัยแอนดรอยด์ในยุคแรก ๆ และไม่รองรับกับการใช้งานในแอนดรอยด์เวอร์ชันปัจจุบันซักเท่าไร
ดังนั้นเพื่อให้ง่ายต่อการเลือกใช้งาน ขอแนะนำให้ใช้งานตามนี้
- รองรับเฉพาะ Portrait - กำหนดค่าเป็น
userPortrait
ที่จะบังคับให้เป็น Portrait บน Phone แต่จะรองรับทั้ง Portrait และ Reverse Portrait เมื่อใช้งานบน Tablet - รองรับเฉพาะ Landscape - กำหนดค่าเป็น
sensorLandscape
หรือuserLandscape
ก็ได้ เพราะให้ผลลัพธ์ที่เหมือนกัน - รองรับทั้ง Portrait และ Landscape - ไม่ต้องกำหนดค่า หรือจะกำหนดค่าเป็น
unspecified
หรือfullSensor
ก็ได้
การกำหนด Screen Orientation ใน App Filter ของ Google Play
ในกรณีที่แอปรองรับแค่อย่างใดอย่างหนึ่งระหว่าง Portrait หรือ Landscape และนักพัฒนาไม่ต้องการให้ผู้ใช้สามารถติดตั้งแอปลงบนอุปกรณ์แอนดรอยด์ที่ไม่รองรับ Orientation นั้น ๆ ด้วย ก็สามารถกำหนดค่า <uses-feature>
ไว้ใน Android Manifest แบบนี้ได้เลย
<!-- AndroidManifest.xml -->
<manifest ...>
<uses-feature android:name="android.hardware.screen.landscape" />
</manifest>
การกำหนดค่าดังกล่าวจะทำให้อุปกรณ์ที่ไม่รองรับ Lanscape ค้นหาแอปบน Google Play ไม่เจอ
- รองรับเฉพาะ Portrait - ใช้
android.hardware.screen.portrait
- รองรับเฉพาะ Landscape - ใช้
android.hardware.screen.landscape
แต่ถ้าแอปสามารถใช้งานได้ทั้ง Portrait และ Landscape ก็ไม่ต้องกำหนดค่าดังกล่าว
การกำหนด Screen Orientation ผ่านโค้ด Kotlin
ถ้าต้องการเปลี่ยนค่า Screen Orientation ที่กำหนดไว้ใน android:screenOrientation
ผ่านโค้ด Kotlin ก็สามารถกำหนดค่าให้กับ requestedOrientation
ที่อยู่ใน Activity ได้เลย
// MainActivity.kt
class MainActivity : AppCompatActivity() {
/* ... */
private fun setReversePortraitScreenOrietation() {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
}
private fun setFullSensorScreenOrientation() {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
}
}
ดักการหมุนหน้าจอ (Screen Rotation)
สามารถดักผ่าน onConfigurationChanged
ได้เลย แต่เพื่อให้คำสั่งทำงานได้อย่างสมบูรณ์ แนะนำให้อ่านต่อในบทความดัก Screen Orientation Event ใน Activity อย่างไรให้ถูกต้อง
สรุป
ถึงแม้ว่าแอปส่วนใหญ่ในปัจจุบันจะรองรับหน้าจอในแนวตั้ง (Portrait) ซะส่วนใหญ่ เพื่อรองรับผู้ใช้งานบน Smartphone เป็นหลัก แต่ก็อย่าลืมว่าทุกวันนี้ก็มีผู้ใช้งานบางส่วนที่ใช้อุปกรณ์แอนดรอยด์ในรูปแบบของ Tablet หรือ Desktop อยู่ด้วย
ดังนั้นเพื่อประสบการณ์ที่ดีสำหรับผู้ใช้งานเหล่านี้ก็อย่าลืมคำนึงถึงการทำแอปให้รองรับการใช้งานในแนวนอน (Landscape) ด้วย ถึงแม้ว่าทุกวันนี้แค่ทำให้รองรับแค่หน้าจอแนวตั้งก็ยังทำไม่ค่อยทันเลย...