ชาว Android Kotlin Developer มาใช้ View Binding กันเถอะ
ใน Android Jetpack มีตัวนึง ชื่อว่า View Binding (ไม่ใช่ Data Binding เน้อ) เอามาใช้แทน Kotlin Synthetic ได้ ลดปัญหาที่เกิดจากการใช้ view ที่มี id ชื่อเดียวกันนั่นเอง
ซึ่งบางครั้งเราก็ได้อ้างอิง view id และ layout ที่ถูกต้องไปแล้ว แต่ดันหาไม่เจอซะงั้น ทำให้แอพแคลช แล้วเรางงว่าเกิดจากอิหยังอะเนี่ยย โอ่ยยยยย เจ็บไปท้างหัวจายตะไมยางทน เจอบัคอีกกี่หนนะคนจายร้ายยยยย~~ เพราะไม่รู้จะแก้ยังไงนี่สิ
ที่มาของการใช้ View Binding ตัวนี้ก็คือ ในทีมแนะนำให้ใช้เพื่อแก้ความเจ็บปวด และสามารถตั้งชื่อ id ของ view ซํ้าได้ แม้อยู่คนละ layout ก็ตาม ทำให้เราไม่เจอ app crash ที่หา view นั้นใน layout ที่เราต้องการไม่เจอนั่นเอง
โดยเจ้า View Binding ตัวนี้นั้นที่อยู่ใน Android Jetpacks ใช้แทน findViewById()
ที่เราเคยใช้มาเมื่ออดีตกาลนั่นเอง
ส่วนความแตกต่างของการทำ View Binding แต่ละแบบ สามารถอ่านที่บล็อกพี่เอกได้เลยจ้า เขียนละเอียดสุดๆ อยากให้อ่านทำความเข้าใจก่อนใช้งานจริงนะ
ย้อนความในอดีตที่ไม่ไกลมากเกี่ยวกับการ binding
ในที่นี้เราจะพูดถึง 2 แบบในบล็อกนี้กัน ก็คือ Kotlin Synthetic กับ View Binding เนอะ
เมื่อเราเป็น Android Kotlin Developer เราเริ่มจะไม่ใช้สิ่งที่เรียกว่า findViewById()
กันแล้ว แหะๆ (ขอไม่เอ่ยถึงมีดตัดเนยนะ) เราเลยใช้ Kotlin Symthetic แทน โดยก่อนอื่นนั้น เราก็ต้องลง plug-in ของ Kotlin ที่ Android Studio ของเรา และเพิ่ม dependency ของ Kotlin ลงไปใน build.gradle
ของ module แบบนี้
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
ในการสร้าง layout นั้น เมื่อก่อนเราจะตั้งชื่อ view id แบบมี underscore เนอะ เรียกว่า snake case เช่น image_avatar
พอมาเป็น Android Kotlin Developer แล้วไซร้ เราเลยต้องตั้งชื่อเป็น camel case กันเพื่อความสวยงามเมื่อนำไปใช้ในโค้ดนั่นเอง เช่น imageAvatar
สมมุติว่า layout นี้นั้นชื่อว่า fragment_profile
แล้วกันเนอะ
แล้วเราก็นำเจ้า view id ไปใช้ เราก็สามารถใช้ชื่อ view id ของเราได้เลย โดยมันจะอ้างอิงจาก synthetic ของ layout นั้นๆมา เมื่อกี้บอกว่าชื่อ fragment_profile
ก็จะเป็นแบบนี้
kotlinx.android.synthetic.main.fragment_profile
วันดีคืนร้าย พอดีว่าแอพของเราใช้ view id ของ ImageView ต่างๆว่า imageAvatar
ในหลายๆที่ เนื่องจากแอพนี้เนี่ยมีเกี่ยวกับการแสดง user ในหลายๆที่ พอมารันในแอพเท่านั้นแหละ พบว่า อ้าว แอพแคลชเพราะหาชื่อ id ของ view ไม่เจอ
(จะแปะรูปแต่หา error แบบนี้ไม่เจอหล่ะ อ่ะช่วยจินตนาการหน่อยน้าาาา)
อ่ะเข้าไปดูโค้ดเราหน่อย อ่ะก็ถูก layout แล้วนี่หว่า อ่ะชื่อก็ถูก แล้วช้านทำอะไรผิดปายยยย~~ เป็นคำถามที่หาคำตอบไม่ได้นานมากแล้ว ตั้งแต่เริ่มเขียน Kotlin แรกๆ เนื่องจากเจอ crashlytics ประมาณนี้บ่อยมาก แล้วก็หาคำตอบไม่เจอว่าเกิดจากอะไร จนมาเจอเรื่อง View Binding เลยอ๋อเลย หลังจากหาคำตอบมาประมาณสองปี ...
แล้วเราจะใช้ View Binding ยังไงดีหล่ะ?
เริ่มจากการ setup ที่ build.gradle
ของ module ไปแบบนี้
android {
...
viewBinding {
enabled = true
}
}
หลังจากที่เราสร้าง layout ของเราไปแล้วนั้น มาที่ class View ของเรา แล้วทำการประกาศตัวแปร binding ซะ
// สำหรับ Activity
private lateinit var binding: ActivityMainBinding
// สำหรับ Fragment
private lateinit var binding: FragmentMainBinding
โดย type ของตัวแปร binding
นี้ จะเป็นไปตามชื่อของ layout ที่อ้างอิงกับ view ของเรา เช่น เรากำลังทำที่หน้า MainFragment
อยู่ มี layout ชื่อว่า fragment_main
ดังนั้นมันจะเป็นชื่อแบบ camel case โดยเป็นชื่อ layout แล้วตามมาด้วย Binding นั่นเอง
หลังจากประกาศตัวแปรเรียบร้อยแล้ว เราจะทำการใส่ค่าให้มันกัน ที่ onCreate()
สำหรับ Activity เพื่อ inflate จาก layout มา และ set view layout เป็น binding.root
// for activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
สำหรับ Fragment เราจะ inflate layout ที่ onCreateView
และทำการ return binding.root
จ้า
// for fragment
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
binding = FragmentMainBinding.inflate(inflater, container, false)
return binding.root
}
การใช้งาน เรียก id ของ view โดยผ่านตัวแปร binding
นั่นเอง
เช่น เราอยากให้ text แสดงอะไรสักอย่างนึง ปกติที่เราใช้ Kotlin Synthetic เป็นแบบนี้เนอะ
textviewUserName.text = "MikkiPastel"
ตอนนี้ที่ใช้ View Binding ก็คือ เอาชื่อตัวแปร binding
ที่ทำไว้ ใส่ไว้หน้าชื่อ view ที่เราต้องการ
binding.textviewUserName.text = "MikkiPastel"
และอย่าลืมลบ Kotlin Synthetic ออกด้วยนะจ๊ะ เดี๋ยวก็ไม่ได้ใช้ View Binding อย่างเต็มที่น้าา
// สำหรับ Activity
import kotlinx.android.synthetic.main.activity_main.*
// สำหรับ Fragment
import kotlinx.android.synthetic.main.fragment_main.*
เท่านี้ก็ใช้งานได้เรียบร้อยจบปิ้งแล้วจ้า
ปล. ถ้า view นั้นใช้หลาย layout ก็ สร้างตัวแปร binding เพิ่มมาอีกนั่นแหละ เพราะมันคนละหน้ากันนี่เนอะ
ข้อจำกัด
ข้อจำกัดของ View Binding ที่ไม่สามารถใช้กับ layout ที่ไม่สามารถใช้ dynamic UI ได้โดยตรงจาก XML และ two-way data binding นั่นเอง ซึ่งทั้งสองอันนั้นวิธีแบบ Data Binding ใช้ได้จ้า
ทั้งนี้ทั้งนั้นก็ขึ้นอยู่กับทีมว่าจะตัดสินใจอะไรกันยังไงหล่ะเนอะ :D แต่ส่วนใหญ่ไม่น่าติด layout ที่ตรงกับข้อจำกัดนี้แหละ
Reference จ้า
อันนี้เกี่ยวกับ View Binding เลย เนื้อหากับที่ทำกันก็ตามๆนี้เลย
อันนี้คือไปหาว่ามา วิธีการตั้งชื่อตัวแปรที่มี underscore เรียกว่าอะไรน้าา ก็เลยไปเจอบล็อกนี้มาเนอะ เผื่อใครสนใจเรื่องมาตรฐานการตั้งชื่อตัวแปรก็เอาไปอ่านต่อกันได้
download แอพอ่านบล็อกใหม่ของเราได้ที่นี่
ติดตามข่าวสารและบทความใหม่ๆได้ที่
และช่องทางใหม่ใน Twiter จ้า