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

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

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

Layout แบบธรรมดา

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

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

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

[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>
[/xml]

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

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

view_yes.xml
[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>
[/xml]

view_no.xml
[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>
[/xml]

การใส่ Include

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

[xml]
<include layout="@layout/view_yes"/>
[/xml]

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

[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">

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

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

</LinearLayout>

</FrameLayout>
[/xml]

กำเนิด Merge Tag

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

[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">

<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>
[/xml]

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

[xml]
<?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>
[/xml]

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

[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>
[/xml]

หวังว่าบทความนี้จะช่วยให้เข้าใจการทำงานของ 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

About author View all posts

admin