[Android] วิธีใช้ Tag Include และ Merge

0

          สวัสดีครับเจอกันอีกครั้งหลังจากหายไปนาน วันนี้เรามาดูวิธีการใช้งาน Tag Include และ Merge ใน XML กัน

          Tag Include และ Merge ถูกสร้างขึ้นมาจากเพราะในการเขียนแอพๆนึงนั้น มักจะเกิดการใช้ View บางอันซ้ำๆกันในหลายๆหน้า ซึ่งมันทำให้ Code ยาวโดยไม่จำเป็นและดูแลรักษายากอีกด้วย เนื่องจาก ถ้าเกิดอยากเปลี่ยน View ตัวที่ใช้ซ้ำๆกันนั้น ต้องไล่เปลี่ยนทุกหน้า ซึ่งเราเองอาจจะลืมแก้ในบางหน้าทำให้แสดงผลผิดพลาดหรือถึงขั้นแอพ Crash กันเลยทีเดียว Include และ Merge จึงทำขึ้นมาเพื่อให้เรานำ Layout ตัวนึงไปใส่ในอีก Layout นึงได้ ถ้ายังไม่เข้าใจเรามาดูตัวอย่างกันดีกว่า

Layout แบบธรรมดา

เริ่มจากการวาง Layout แบบปกติกันก่อน ด้วย activiy_include.xml

หน้าตาคร่าวๆ

หน้าตาคร่าวๆ

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        android:src="@drawable/background" />

    <LinearLayout
        android:layout_gravity="center_horizontal|bottom"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:text="Yes"
            android:layout_margin="8dp"
            android:background="#4CAF50"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <Button
            android:text="No"
            android:layout_margin="8dp"
            android:background="#F44336"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>

</FrameLayout>

แยกส่วนที่ต้องการเป็น Layout ใหม่

หลังจากได้ Layout แบบปกติมาแล้ว เราก็แยกชิ้นของปุ่ม Yes No ออกมาเป็นคนละ Layout แยกออกเป็น view_yes.xml และ view_no.xml

view_yes.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:text="Yes"
        android:layout_margin="8dp"
        android:background="#4CAF50"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</FrameLayout>

view_no.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:text="Yes"
        android:layout_margin="8dp"
        android:background="#4CAF50"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</FrameLayout>

การใส่ Include

โดยแต่ละ Layout ที่แยกออกมาเป็น FrameLayout ที่ข้างในใส่ Button เอาไว้ เอาละเรามาใส่ Include กัน เวลาจะใส่ก็เอาไปวางไว้ที่ตำแหน่งที่จะให้ view ของเราไปอยู่แบบนี้

<include layout="@layout/view_yes"/>

เวลาใส่จริงจะเป็นแบบนี้

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        android:src="@drawable/background" />

    <LinearLayout
        android:layout_gravity="center_horizontal|bottom"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <include layout="@layout/view_yes"/>

        <include layout="@layout/view_no"/>

    </LinearLayout>

</FrameLayout>

กำเนิด Merge Tag

เวลาดู Preview ก็ทำงานได้เหมือนปกติ แต่สังเกตดูว่าใน view_yes กับ view_no นั้นเรามี FrameLayout ครอบอยู่ ซึ่งไม่ได้มีประโยชน์อะไรเป็นใช้เพิ่ม Layout โดยไม่จำเป็นอีกด้วย ดูแล้วมันคล้ายๆแบบนี้

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        android:src="@drawable/background" />

    <LinearLayout
        android:layout_gravity="center_horizontal|bottom"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent">

             <Button
                  android:text="Yes"
                  android:layout_margin="8dp"
                  android:background="#4CAF50"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content" />

          </FrameLayout>

        <FrameLayout
              android:layout_width="match_parent"
              android:layout_height="match_parent">

              <Button
                  android:text="Yes"
                  android:layout_margin="8dp"
                  android:background="#4CAF50"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content" />

          </FrameLayout>

    </LinearLayout>

</FrameLayout>

ดังนั้นจึงเกิด Tag Merge ขึ้นมา เพื่อเอามาแทนตัว Parent Layout (FrameLayout ของ view_yes.xml และ view_no.xml) การทำงานมันคือเวลาเจอ Tag Merge มันจะมองข้ามไปเหมือนกับเอา Layout ด้านใน Merge ไป Include เลยแบบนี้

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:text="No"
        android:layout_margin="8dp"
        android:background="#F44336"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</merge>

ทำให้แอพมองเห็น Layout เป็นแบบตอนแรกเลยคือแบบนี้ เป็นเหมือนการมองข้าม Tag Merge ไปนั้นเอง

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        android:src="@drawable/background" />

    <LinearLayout
        android:layout_gravity="center_horizontal|bottom"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:text="Yes"
            android:layout_margin="8dp"
            android:background="#4CAF50"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <Button
            android:text="No"
            android:layout_margin="8dp"
            android:background="#F44336"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>

</FrameLayout>

หวังว่าบทความนี้จะช่วยให้เข้าใจการทำงานของ Include และ Merge มากขึ้นนะครับ

แหล่งอ้างอิง
https://developer.android.com/training/improving-layouts/reusing-layouts.html
http://android-developers.blogspot.com/2009/03/android-layout-tricks-3-optimize-by.html
http://stackoverflow.com/questions/8834898/what-is-the-purpose-of-androids-merge-tag-in-xml-layouts

Facebook Comments
Share.

About Author

Comments are closed.