สวัสดีครับเจอกันอีกครั้งหลังจากหายไปนาน วันนี้เรามาดูวิธีการใช้งาน 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