RelativeLayout — สาระสำคัญ กฎเค้าโครงในแอปพลิเคชัน Android

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-02-24 เวลาอ่าน: 9 นาที

เราอธิบายสาระสำคัญของ RelativeLayout — ViewGroup ใน Android SDK สำหรับจัดตำแหน่งองค์ประกอบย่อยโดยสัมพันธ์กันหรือสัมพันธ์กับคอนเทนเนอร์พาเรนต์ แตกต่างจาก LinearLayout ซึ่งจัดเรียงองค์ประกอบตามลำดับอย่างเคร่งครัด RelativeLayout ช่วยให้คุณวางองค์ประกอบใดๆ ทางซ้าย ขวา บน ล่าง หรือกึ่งกลางโดยสัมพันธ์กับองค์ประกอบอื่นใดๆ ตาม ID ของมัน ทำให้ RelativeLayout สะดวกสำหรับเค้าโครงที่ซับซ้อนและทับซ้อนกันโดยไม่ต้องซ้อนกัน กฎพื้นฐานอธิบายไว้ใน เอกสารประกอบของ Android Developers

ประเด็นสำคัญ

  • layout_below / layout_above — ยึดองค์ประกอบไว้เหนือหรือใต้ขององค์ประกอบที่ระบุตาม ID; แอตทริบิวต์หลักสำหรับสร้างโฟลว์
  • alignParentTop / alignParentBottom — ยึดขอบขององค์ประกอบเข้ากับขอบที่สอดคล้องกันของพาเรนต์; ทำงานทั้งสี่ด้าน
  • การจัดกึ่งกลาง — centerInParent (กึ่งกลางของทั้งสองแกน), centerHorizontal (กึ่งกลางบน X), centerVertical (กึ่งกลางบน Y)
  • toLeftOf / toRightOf — วางองค์ประกอบทางซ้ายหรือขวาขององค์ประกอบที่ระบุ โดยไม่ทับซ้อนกัน
  • กฎการทับซ้อน — หากกฎขัดแย้งกัน (เช่น alignParentTop และ below ของอีกองค์ประกอบหนึ่ง) กฎที่ประกาศล่าสุดใน XML จะได้รับลำดับความสำคัญ

RelativeLayout คืออะไร?

RelativeLayout — ViewGroup ที่ถูกนำมาใช้ใน Android SDK ตั้งแต่ API Level 1 ซึ่งจัดตำแหน่งองค์ประกอบย่อยผ่านกฎแบบประกาศ (layout rules) โดยสัมพันธ์กับพาเรนต์หรือองค์ประกอบย่อยอื่นๆ แต่ละกฎถูกกำหนดด้วยแอตทริบิวต์ XML เช่น android:layout_above, android:layout_below, android:layout_toLeftOf โดยมีค่า ID ขององค์ประกอบเป้าหมาย

ก่อนที่ RelativeLayout จะปรากฏ นักพัฒนาต้องใช้ LinearLayout ที่ซ้อนกันสำหรับทุกตำแหน่งที่ไม่ได้มาตรฐาน — สิ่งนี้นำไปสู่การซ้อนกันลึกและการเรนเดอร์ที่ช้า RelativeLayout แก้ปัญหานี้โดยเสนอการกำหนดตำแหน่งแบบสัมพัทธ์ในระดับลำดับชั้นเดียว อย่างไรก็ตาม ความยืดหยุ่นของมันถูกจำกัดเมื่อเทียบกับ ConstraintLayout สมัยใหม่: RelativeLayout ไม่รองรับเชน, แบริเออร์, ไกด์ไลน์ หรือขนาดแบบเปอร์เซ็นต์

RelativeLayout มีคุณสมบัติหลักสองประการ: onMeasure ผ่านครั้งเดียว (แตกต่างจาก LinearLayout ที่มี weight ซึ่งต้องผ่านสองครั้ง) และ การขึ้นอยู่กับลำดับการประกาศ — หากองค์ประกอบ A อ้างอิงถึงองค์ประกอบ B และ B ถูกประกาศหลังจาก A B ต้องมีขนาดที่ทราบในเวลาที่ทำการวัดของ A ตามคู่มือนักพัฒนา Android (2024) RelativeLayout ทำการวัดในครั้งเดียวหากกฎทั้งหมดอ้างอิงถึงองค์ประกอบที่วัดแล้ว มิฉะนั้น จะต้องมีการวัดครั้งที่สอง ซึ่งลดประสิทธิภาพ

เมื่อใดที่จำเป็นต้องใช้ RelativeLayout

RelativeLayout เหมาะสมสำหรับเค้าโครงง่ายๆ ที่มี 3–7 องค์ประกอบซึ่งต้องการการกำหนดตำแหน่งแบบสัมพัทธ์ (ป้ายกำกับเหนือปุ่ม, ไอคอนทางขวาของข้อความ, แผงด้านล่างของหน้าจอ) สำหรับโปรเจกต์ใหม่ แนะนำให้ใช้ ConstraintLayout แต่ RelativeLayout ยังคงใช้อย่างแพร่หลายในโคดเก่าและไลบรารี

กฎการกำหนดตำแหน่ง: relative และ align

RelativeLayout ใช้กฎสองประเภท: กฎ relative (การกำหนดตำแหน่งสัมพัทธ์กับองค์ประกอบอื่น) และกฎ align (การยึดกับพาเรนต์) องค์ประกอบย่อยแต่ละตัวสามารถมีกฎได้ไม่จำกัดจำนวน แต่กฎที่ขัดแย้งกัน (เช่น alignParentTop และ below ของอีกองค์ประกอบหนึ่ง) จะถูกแก้ไขโดยให้ความสำคัญกับแอตทริบิวต์ที่ประกาศล่าสุด

กฎ relative: - android:layout_above="@id/target" — ขอบล่างขององค์ประกอบถูกยึดกับขอบบนของเป้าหมาย - android:layout_below="@id/target" — ขอบบนขององค์ประกอบถูกยึดกับขอบล่างของเป้าหมาย - android:layout_toLeftOf="@id/target" — ขอบขวาถูกยึดกับขอบซ้ายของเป้าหมาย - android:layout_toRightOf="@id/target" — ขอบซ้ายถูกยึดกับขอบขวาของเป้าหมาย - android:layout_toStartOf="@id/target" — คล้ายกับ toLeftOf สำหรับตำแหน่งที่ตั้ง RTL - android:layout_toEndOf="@id/target" — คล้ายกับ toRightOf สำหรับ RTL

กฎ align (กับพาเรนต์): - android:layout_alignParentTop="true" — ขอบบนขององค์ประกอบตรงกับขอบบนของพาเรนต์ - android:layout_alignParentBottom="true" — ขอบล่างตรงกับขอบล่างของพาเรนต์ - android:layout_alignParentLeft="true" — ขอบซ้ายตรงกับขอบซ้ายของพาเรนต์ - android:layout_alignParentRight="true" — ขอบขวาตรงกับขอบขวาของพาเรนต์ - android:layout_alignParentStart และ android:layout_alignParentEnd — สำหรับ RTL

กฎ align กับองค์ประกอบอื่น: - android:layout_alignTop="@id/target" — ด้านบนขององค์ประกอบตรงกับด้านบนของเป้าหมาย - android:layout_alignBottom, android:layout_alignLeft, android:layout_alignRight, android:layout_alignStart, android:layout_alignEnd — คล้ายกัน - android:layout_alignBaseline="@id/target" — การจัดแนวตามเส้นฐานข้อความ (มีประโยชน์สำหรับสตริงที่มีขนาดฟอนต์ต่างกัน)

การจัดกึ่งกลางและลำดับ Z

การจัดกึ่งกลางใน RelativeLayout ถูกกำหนดโดยสามแอตทริบิวต์: android:layout_centerInParent="true" (กึ่งกลางของพาเรนต์บนทั้งสองแกน), android:layout_centerHorizontal="true" (กึ่งกลางแนวนอน) และ android:layout_centerVertical="true" (กึ่งกลางแนวตั้ง) การจัดกึ่งกลางเข้ากันได้กับกฎอื่นๆ: องค์ประกอบสามารถถูกจัดกึ่งกลางแนวนอนในขณะที่ถูกยึดกับขอบล่างของพาเรนต์

ลำดับ Z (ลำดับการซ้อนทับ) ใน RelativeLayout ถูกกำหนดโดยลำดับการประกาศองค์ประกอบใน XML องค์ประกอบที่ประกาศแรกจะถูกวาดก่อน (จะอยู่ด้านล่าง) องค์ประกอบสุดท้าย — สุดท้าย (จะอยู่ด้านบน) หากคุณต้องการเปลี่ยนลำดับการซ้อนทับโดยไม่เปลี่ยน XML ให้ใช้ android:elevation (ตั้งแต่ API 21) — องค์ประกอบที่มี elevation สูงกว่าจะถูกวาดไว้ด้านบน สำหรับเวอร์ชันต่ำกว่า API 21 ลำดับการซ้อนทับจะถูกควบคุมโดยลำดับการประกาศเท่านั้น

สำคัญ: RelativeLayout ไม่รองรับแอตทริบิวต์ android:elevation สำหรับพาเรนต์ — แต่ละองค์ประกอบควบคุม elevation ของตัวเอง เมื่อกฎการกำหนดตำแหน่งและ elevation ขัดแย้งกัน (เช่น องค์ประกอบที่ทับซ้อนกัน) elevation มีลำดับความสำคัญสำหรับการเรนเดอร์ แต่ไม่ใช่สำหรับการกำหนดตำแหน่ง — องค์ประกอบที่มี elevation สูงกว่าสามารถทับซ้อนอีกองค์ประกอบหนึ่งทางสายตา แม้ว่ากฎเค้าโครงของมันจะวางไว้ "ด้านหลัง"

ตัวอย่าง: เค้าโครง XML ด้วย RelativeLayout

ตัวอย่างที่ 1: โปรไฟล์ผู้ใช้

รูปประจำตัวกึ่งกลางด้านบน ชื่อใต้รูปประจำตัว สถานะใต้ชื่อ ปุ่มดำเนินการด้านล่างของหน้าจอ องค์ประกอบทั้งหมดใช้กฎ relative สำหรับการยึดตามลำดับ

xml
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/avatar"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="32dp"
        android:src="@drawable/avatar_placeholder" />

    <TextView
        android:id="@+id/user_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/avatar"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="12dp"
        android:text="อีวาน อีวานอฟ"
        android:textSize="20sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/user_status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/user_name"
        android:layout_centerHorizontal="true"
        android:text="ออนไลน์"
        android:textColor="@color/green" />

    <Button
        android:id="@+id/edit_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="24dp"
        android:text="แก้ไขโปรไฟล์" />

</RelativeLayout>

รูปประจำตัวถูกยึดกับด้านบนผ่าน marginTop + centerHorizontal ชื่ออยู่ใต้รูปประจำตัวผ่าน layout_below สถานะอยู่ใต้ชื่อ และปุ่มถูกยึดกับขอบล่างของพาเรนต์ผ่าน alignParentBottom องค์ประกอบทั้งหมดเป็นอิสระต่อกัน — ไม่มีเชนหรือการซ้อนกัน

ตัวอย่างที่ 2: แผงที่มีไอคอนและป้าย

ไอคอนที่มีป้ายสีแดง (วงกลมพร้อมตัวเลข) ที่มุมขวาบน ป้ายถูกวางตำแหน่งโดยสัมพันธ์กับไอคอนผ่านการจัดแนวกับขอบของมันด้วยมาร์จินติดลบสำหรับการซ้อนทับ

xml
<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@drawable/ic_notification" />

    <TextView
        android:id="@+id/badge"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_alignTop="@+id/icon"
        android:layout_alignRight="@+id/icon"
        android:layout_marginTop="-6dp"
        android:layout_marginRight="-6dp"
        android:gravity="center"
        android:background="@drawable/badge_background"
        android:text="3"
        android:textColor="@android:color/white"
        android:textSize="10sp" />

</RelativeLayout>

ป้ายถูกยึดกับขอบบนและขวาของไอคอน มาร์จินติดลบ (-6dp) เลื่อนป้ายออกไปด้านนอก สร้างเอฟเฟกต์การทับซ้อนของขอบไอคอน นี่เป็นรูปแบบที่นิยมสำหรับการแจ้งเตือน ซึ่งหากไม่มี RelativeLayout จะต้องใช้ FrameLayout หรือการวาดแบบกำหนดเอง

ตัวอย่างที่ 3: หน้าจอเข้าสู่ระบบด้วย RelativeLayout

ฟอร์มเข้าสู่ระบบ: โลโก้กึ่งกลางด้านบน ช่องอีเมลด้านล่าง ช่องรหัสผ่านด้านล่างอีเมล ปุ่ม "เข้าสู่ระบบ" ด้านล่างรหัสผ่าน ลิงก์ "ลงทะเบียน" ยึดติดกับด้านล่าง องค์ประกอบทั้งหมดถูกยึดตามลำดับผ่าน layout_below

xml
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="24dp">

    <TextView
        android:id="@+id/logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="48dp"
        android:text="MyApp"
        android:textSize="32sp"
        android:textStyle="bold" />

    <EditText
        android:id="@+id/email_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/logo"
        android:layout_marginTop="32dp"
        android:hint="Email" />

    <EditText
        android:id="@+id/password_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/email_input"
        android:layout_marginTop="16dp"
        android:hint="รหัสผ่าน"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/password_input"
        android:layout_marginTop="24dp"
        android:text="เข้าสู่ระบบ" />

    <TextView
        android:id="@+id/register_link"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="16dp"
        android:text="ยังไม่มีบัญชี? ลงทะเบียน"
        android:textColor="@color/primary" />

</RelativeLayout>

หน้าจอใช้องค์ประกอบ 5 รายการในระดับลำดับชั้นเดียว โฟลว์จากบนลงล่าง (โลโก้ → อีเมล → รหัสผ่าน → ปุ่ม) ทำได้ผ่าน layout_below และลิงก์ถูกดันลงด้านล่างผ่าน alignParentBottom สำหรับฟังก์ชันการทำงานเดียวกัน LinearLayout จะต้องใช้คอนเทนเนอร์ที่ซ้อนกันสองตัว (หนึ่งตัวสำหรับกลุ่มบน, หนึ่งตัวสำหรับลิงก์ที่มี weight)

RelativeLayout vs ConstraintLayout: การเปรียบเทียบ

การเปรียบเทียบ ViewGroup สองตัวสำหรับการกำหนดตำแหน่งแบบสัมพัทธ์: RelativeLayout (คลาสสิก, API 1+) และ ConstraintLayout (สมัยใหม่, Jetpack) เกณฑ์: ความยืดหยุ่น, ประสิทธิภาพ, การรองรับ RTL และความสามารถในการปรับเปลี่ยน

คุณลักษณะRelativeLayoutConstraintLayout
ขนาดเปอร์เซ็นต์ไม่ (เฉพาะแบบคงที่และ match_parent)ใช่ (width_percent, height_percent, guideline_percent)
การรองรับ RTLผ่าน start/end (API 17+)ในตัว
Chain / เชนไม่ใช่ (spread, spread_inside, packed)
Barrier / Group / Flowไม่ใช่ (ตัวช่วยเสมือน)
แอนิเมชัน MotionLayoutไม่ใช่
รอบ onMeasure1 (ไม่มีวงจรการพึ่งพา)2 (เสมอ แต่ได้รับการปรับให้เหมาะสม)
การจัดกึ่งกลางcenterInParent, centerHorizontal, centerVerticalผ่าน bias (0.0–1.0) พร้อมข้อจำกัดตรงข้าม
เมื่อใดควรใช้โคดเก่า, เค้าโครงง่ายๆ ที่มี 3–7 องค์ประกอบโปรเจกต์ใหม่, หน้าจอซับซ้อน, เค้าโครงปรับเปลี่ยนได้

RelativeLayout ด้อยกว่า ConstraintLayout ในเกือบทุกด้านยกเว้นหนึ่ง: มันถูกสร้างใน Android SDK ตั้งแต่ API 1 และไม่ต้องการการพึ่งพาเพิ่มเติม สำหรับโปรเจกต์ที่ยังใช้ minSdk ต่ำกว่า API 14 (Android 4.0) RelativeLayout เป็นตัวเลือกมาตรฐานเดียวสำหรับการกำหนดตำแหน่งแบบสัมพัทธ์ ในกรณีอื่นๆ ทั้งหมด Google แนะนำ ConstraintLayout

คำถามที่พบบ่อย

ทำไมองค์ประกอบ RelativeLayout ไม่แสดง?

สาเหตุที่เป็นไปได้มากที่สุด คือการขาดกฎการกำหนดตำแหน่งที่เพียงพอ แต่ละองค์ประกอบใน RelativeLayout ต้องมีกฎแนวนอนอย่างน้อยหนึ่งกฎ (alignParentLeft, toRightOf, centerHorizontal) และกฎแนวตั้งหนึ่งกฎ (alignParentTop, below, centerVertical) หากไม่มีกฎ องค์ประกอบจะอยู่ในตำแหน่ง (0,0) และอาจถูกซ่อนไว้ใต้องค์ประกอบอื่นหรือนอกหน้าจอ สาเหตุที่สองคือการพึ่งพาแบบวงจร (องค์ประกอบ A เชื่อมกับ B, B เชื่อมกับ A) ซึ่งนำไปสู่พฤติกรรมที่ไม่สามารถคาดเดาได้

จะจัดองค์ประกอบให้อยู่กึ่งกลางหน้าจอใน RelativeLayout ได้อย่างไร?

ใช้แอตทริบิวต์ android:layout_centerInParent="true" มันจะจัดกึ่งกลางองค์ประกอบบนทั้งสองแกนพร้อมกัน หากต้องการเฉพาะแนวนอน — android:layout_centerHorizontal="true" เฉพาะแนวตั้ง — android:layout_centerVertical="true" การจัดกึ่งกลางทำงานร่วมกับมาร์จิน — องค์ประกอบจะถูกเลื่อนโดยสัมพันธ์กับกึ่งกลางตามระยะที่ระบุ

สามารถใช้ RelativeLayout ใน RecyclerView ได้หรือไม่?

ได้ แต่ไม่แนะนำ RelativeLayout ดำเนินการ onMeasure สองครั้งเมื่อมีการพึ่งพาแบบวงจร ซึ่งช้ากว่า ConstraintLayout 15–30% ในรายการ RecyclerView สำหรับเค้าโครงรายการของ RecyclerView ให้ใช้ ConstraintLayout — มันให้ลำดับชั้นแบบเรียบที่มีเวลาในการวัดน้อยที่สุด หาก RelativeLayout ถูกใช้ในโปรเจกต์เก่าอยู่แล้ว ให้ตรวจสอบว่าองค์ประกอบไม่สร้างการพึ่งพาแบบวงจร และวัด FPS การเลื่อนผ่าน Profile GPU Rendering

layout_margin แตกต่างจาก layout_marginTop ใน RelativeLayout อย่างไร?

android:layout_margin กำหนดมาร์จินทุกด้านพร้อมกัน android:layout_marginTop — เฉพาะด้านบน แอตทริบิวต์ที่เฉพาะเจาะจงมากกว่าจะได้รับความสำคัญ: หากทั้ง layout_margin (16dp) และ layout_marginTop (8dp) ถูกตั้งค่า มาร์จินด้านบนจะเป็น 8dp ใน RelativeLayout มาร์จินทำงานโดยสัมพันธ์กับข้อจำกัด ไม่ใช่โดยสัมพันธ์กับองค์ประกอบที่อยู่ติดกัน: layout_marginTop กับ layout_below="@id/target" คือมาร์จินจากขอบบนขององค์ประกอบถึงขอบล่างของเป้าหมาย

สรุป

  • RelativeLayout — ViewGroup สำหรับจัดตำแหน่งองค์ประกอบโดยสัมพันธ์กันหรือกับพาเรนต์ผ่านกฎแบบประกาศ
  • กฎการยึด — layout_below/above (แนวตั้ง), layout_toLeftOf/toRightOf (แนวนอน), alignParentTop/Bottom (กับพาเรนต์)
  • การจัดกึ่งกลาง — centerInParent (กึ่งกลาง), centerHorizontal (บน X), centerVertical (บน Y) สำหรับการจัดแนวอย่างรวดเร็ว
  • ลำดับ Z — กำหนดโดยลำดับการประกาศใน XML; elevation (API 21+) เปลี่ยนลำดับ Z ระหว่างการเรนเดอร์
  • ข้อจำกัด — ไม่มีขนาดเปอร์เซ็นต์, เชน, แบริเออร์; การพึ่งพาแบบวงจรทำให้เกิดรอบ onMeasure ที่สอง
  • ประสิทธิภาพ — 1 รอบ onMeasure โดยไม่มีวงจร แต่ด้อยกว่า ConstraintLayout ในเค้าโครงที่ซับซ้อน
  • คำแนะนำ — ใช้ในโปรเจกต์เก่า; สำหรับหน้าจอใหม่ให้เลือก ConstraintLayout

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม