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

Share.

About Author

Comments are closed.