เปลี่ยนมาใช้ Fragment กันเถอะ

โดยปกติแล้วเวลาเราทำแอปฯขึ้นมาสักหนึ่งตัว แน่นอนว่าส่วนใหญ่ต้องมีมากกว่า1หน้าอยู่แล้ว แต่ละหน้าก็จะมี Layout ที่แตกต่างกันอยู่มากมาย
ยกตัวอย่าง เช่น

Activity A จะมี Layout A อยู่หนึ่งตัว ส่วนอีกหน้าหนึ่งคือ Activity B จะมี Layout B อยู่หนึ่งตัวเหมือนกัน ซึ่งเป็น Layout คนละตัวกันกับ Layout A โดยกรณีแบบนี้ยังดูปกติอยู่นะครับ แต่ผมจะขอยกตัวอย่างอีกสักหนึ่งตัวอย่างเพื่อที่จะได้เห็นภาพกันมากยิ่งขึ้น

เงื่อนไขมีอยู่ว่า Layout 1 ใน Activity A และ B จะแตกต่างกัน แต่ Layout 2 นั้นต้องเหมือนกัน ซึ่งแน่นอนว่าสามารถทำได้อย่างง่ายดายเลย โดยการ copy 
โค้ด xml ในส่วนของ Layout 2 ไปแปะไว้ใน Activity A และ B ได้เลย แค่นี้จบ…
แต่ ! อย่าลืมว่าการทำแบบนี้เกิดปัญหาโค้ดซ้ำซ้อนไหม ? ใช่ โค้ดซ้ำซ้อนครับ
เพราะลองคิดดูว่า ถ้าเกิดมีการแปะ Layout แบบนี้ไว้ในทุกๆ Activity แล้วสมมุติว่า
มีสัก 5 10 15 Activity ล่ะ หากวันดีคืนดีอยากจะปรับเปลี่ยน Layout 2 สักนิด
สักหน่อย ก็ต้องไปนั่งไล่แก้โค้ด xml ในทุกๆ Activity เลยนะ แค่คิดก็ปวดหัวแล้ว 😵
งั้นเอาแบบนี้ดีกว่า เอา Layout ไปแปะไว้บนสิ่งๆหนึ่ง แล้วก็นำสิ่งๆนั้นไปแปะไว้บน Activity อีกทีหนึ่ง สิ่งๆนั้นก็คือ Fragment นั่นเองงงงง


Fragment คืออะไร ?

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


Fragment Transaction

FragmentTransaction มีหน้าที่จัดการ Fragment เพื่อให้ไปแสดงผลในอีก Layout ตามที่ต้องการ ทั้งการเพิ่ม Fragment ลงไปใน Layout หรือจะเป็นการลบออกจาก Layout ซึ่ง FragmentTransaction นี้ ช่วยให้เรามาสามารถถอด Fragment ออกแล้วใส่ Fragment ตัวใหม่เข้าไปแทนหรือจะเป็นการสลับ Fragment ไปมาๆ ก็จัดการได้โดยใช้ FragmentTransaction นั่นเองครับ โดยมี 3 คำสั่งที่จะพูดถึง ดังนี้

  • add() : คำสั่งนี้จะทำหน้าที่เพิ่ม Fragment เพิ่มลงไปทำให้สามารถซ้อนทับกันได้
  • replace() : คำสั่งนี้จะเป็นการแปะ Fragment ตัวใหม่ทับตัวเก่าที่มีอยู่ก่อนหน้านี้
  • addToBackStack() : คำสั่งนี้จะทำการเก็บ Stack ก่อนหน้าไว้ให้เรื่อยๆ โดยที่
    เมื่อมีการกดปุ่ม Back กลับมาก็จะทำการเรียก Fragment ตัวก่อนหน้ามาแสดงผลโดยที่ไม่ต้องทำการสร้างใหม่ ส่วนมากจะนิยมใช้คำสั่ง replace() คู่กับ addToBackStack() เพราะแอปฯส่วนมากจะเป็นแบบซ้อนกันไปเรื่อยๆ เวลากด Back กลับมาก็จะได้ดึง stack เก่ามาใช้งานต่อได้ทันที

เริ่มใช้งาน Fragment กันเลย

Class ทั้งหมด

  • MainActivity.java
  • Callback.java
  • HomeFragment.java
  • SecondFragment.java
  • ThirdFragment.java

ก่อนอื่นเตรียมไฟล์ Layout

activity_main.xml

ใน activity_main.xml จะทำการสร้าง FrameLayout เป็นพื้นที่ว่างๆเอาไว้สำหรับเรียก Fragment มาแปะไว้เพื่อแสดงผล

fragment_first.xml
fragment_second.xml
fragment_third.xml
Layout ของ Fragment ทั้ง 3

เตรียม Class Java

Callback.java
Note : Interface Callback สร้างไว้สำหรับเป็นตัวกลางเพื่อให้ Fragment กับ Activity สามารถติดต่อกันได้
MainActivity.java

เมื่อมีการเรียกใช้งาน MainActivity ครั้งแรก ก็จะทำการแปะ Layout ของ HomeFragment ลงไปให้เรียบร้อยผ่านคำสั่ง add(…) นั่นเอง และในส่วนที่ได้ implement Callback เอาไว้ก็เพราะว่าจริงๆแล้ว Callback ได้สร้างเป็น Interface เพื่อเอาไว้ติดต่อระหว่าง Fragment กับ Activity โดยมี method someEvent(…) 
ทำหน้าที่รับ Fragment ที่ส่งมาจาก Class Fragment ต่างๆ จากนั้นเรียก method replaceFragment(…) เพื่อทำการแปะ Fragment ตัวใหม่ทับตัวเก่า โดย Fragment ตัวใหม่ที่ได้รับมาจาก someEvent() เข้าไปแทนและมีการเก็บ Stack ก่อนหน้าเอาไว้อีกด้วย

FirstFragment.java
SecondFragment.java
ThirdFragment.java

ในส่วนของ HomeFragment และ SecondFragment นั้นก็ไม่มีอะไรมาก มีการ findViewById ปุ่มและก็สั่ง setOnClickListener เพื่อที่จะกดแล้วจะไปยังหน้าถัดไป
โดยเรียกใช้ Interface Callback เป็นตัวกลางการติดต่อกันระหว่าง Fragment กับ Activity และใน method onAttach(…) จะทำงานเมื่อ Fragment ถูกร้องขอให้แปะบน Activity โดยจะทำการเช็คก่อนว่า Activity ได้ implement Callback หรือยัง
และสุดท้ายเมื่อมีการกดปุ่ม คำสั่ง onClick(…) ก็จะถูกเรียกใช้ตามเงื่อนไข 
โดยประกาศ Fragment ที่ต้องการจะนำไปแปะไว้บน Activity จากนั้นส่งไปยัง method someEvent(…) เพื่อให้ Activity เรียกใช้งานต่อไป

ผลลัพธ์ : เมื่อสร้างไฟล์ทั้งหมดครบแล้วก็ลองกดรันกันได้เลยครับ แล้วก็อย่าลืมทำความเข้าใจในส่วนต่างๆของโค้ดด้วยนะครับ :=)

สรุป

Fragment เกิดมาเพื่อแก้ปัญหาการทำงานของ Layout ที่ซับซ้อน และค่อนข้างจะคล้ายกับ Activity แต่ทำงานด้วยตัวของมันเองไม่ได้ ต้องอาศัยไปแปะไว้บน Activity
ซึ่งช่วยให้การทำงานต่างๆยืดหยุ่นขึ้นมากโดยที่แบ่งการทำงานต่างๆไว้ในแต่ละ Fragment ไป ไม่ต้องยัดการทำงานทุกๆอย่างไว้บน Activity เดียว และยังช่วยลดปัญหาโค้ดซ้ำซ้อนได้ดีอีกด้วย โดยการแปะทุกอย่างไว้บน Fragment แล้วเอา Fragment ไปแปะไว้บน Activity อีกที ซึ่งการทำทุกอย่างบน Fragment จะทำให้โค้ดจัดการได้ง่ายกว่าเผื่อต้องการจะแก้ไขหรือเพิ่มลบนู้นนี่ และสิ่งที่ไม่ควรทำก็คือทั้งแอปฯห้ามมี Activity เดียว แล้วแปะ Fragment ทั้งหมดเอาไว้ใน Activity นั้น
แล้วสลับไปสลับมา เพราะจะทำให้การจัดการโค้ดจะยุ่งยาก ควรแบ่งเป็น Activity ย่อยๆจะช่วยให้การจัดการโค้ดง่ายขึ้นอีกด้วย