View Binding ช่วยให้เขียนโค้ดที่โต้ตอบกับมุมมองได้ง่ายขึ้น ต่อไปนี้คือวิธีตั้งค่าในโปรเจ็กต์ Android Gradle ของคุณ
นักพัฒนา Android ส่วนใหญ่อาจคุ้นเคยกับเวอร์ชันคลาสสิก findViewById()
วิธี. ส่ง ID ของ Views รายการใดรายการหนึ่งในเลย์เอาต์ XML ของคุณไปให้ จากนั้นระบบจะส่งคืนการอ้างอิงไปยัง View เวอร์ชันที่สูงเกินจริง นั่นคือทั้งหมดที่สมมติว่าคุณส่ง ID ที่ถูกต้องและมีมุมมองอยู่จริง findViewById()
ไม่มีการเช็คอินในตัวเพื่อป้องกันไม่ให้คุณพยายามดึงข้อมูลมุมมองที่คุณไม่สามารถดึงข้อมูลได้ เข้าสู่การผูกมุมมอง
แทนที่จะใช้ findViewById()
ในแต่ละมุมมองที่คุณต้องการ View Binding จะสร้างคลาสการเชื่อมโยงสำหรับ XML โครงร่างแต่ละรายการโดยอัตโนมัติ แต่ละมุมมองที่มี ID จะถูกเพิ่มลงในชั้นเรียนโดยอัตโนมัติ ดังนั้นคุณจึงสามารถอ้างอิงได้โดยตรง
การเพิ่ม View Binding ให้กับโปรเจ็กต์ Android Gradle นั้นง่ายมาก
การตั้งค่า Gradle
View Binding ถูกเปิดใช้งานในระดับโมดูลใน Gradle หากคุณมีหลายโมดูล คุณจะต้องเปิดใช้งานโมดูลแยกกันสำหรับแต่ละโมดูล
ใน android
บล็อกในระดับโมดูลของคุณ build.gradle
เพิ่มตัวเลือกเพื่อเปิดใช้งาน View Binding
android {
...
buildFeatures {
viewBinding true
}
}
อาจมีคำเตือนเกี่ยวกับการเข้าถึงที่ผิดกฎหมาย แต่นั่นเป็นข้อบกพร่องของขุยและสามารถเพิกเฉยได้อย่างปลอดภัย
ซิงค์โปรเจ็กต์และ View Binding จะถูกเปิดใช้งาน มันง่ายมาก
การใช้การผูกมุมมอง
มีหลายวิธีในการใช้ View Binding แต่ก่อนที่จะเกิดเหตุการณ์เช่นนี้ เรามาพูดถึงวิธีการสร้างคลาสการโยงกันก่อน
ไวยากรณ์ชื่อคลาส
สมมติว่าคุณมี XML โครงร่างชื่อ some_layout.xml
. คลาสการผูกที่สอดคล้องกันจะถูกตั้งชื่อ SomeLayoutBinding
. รูปแบบนั้นใช้สำหรับไฟล์ทั้งหมด
แต่ละคำ (คั่นด้วยขีดล่างในชื่อไฟล์) จะถูกขึ้นต้นด้วยตัวพิมพ์ใหญ่ และขีดล่างจะถูกลบออก จากนั้นคำว่า "Binding" จะถูกเพิ่มต่อท้าย
การสร้างอินสแตนซ์ด้วยมุมมองที่มีอยู่
หากคุณขยายไฟล์เลย์เอาต์แล้วและคุณมีการอ้างอิงถึงรูทของเลย์เอาต์ คุณสามารถบอกให้คลาสการเชื่อมโยง View ใช้เลย์เอาต์ที่มีอยู่ได้
คอตลิน:
val binding = SomeLayoutBinding.bind(someLayoutRoot /* should be a View instance */)
ชวา:
SomeLayoutBinding binding = SomeLayoutBinding.bind(someLayoutRoot /* should be a View instance */);
ตัวอย่างเช่น หากคุณต้องการใช้คลาสการโยงใน Fragment มันจะมีลักษณะดังนี้
คอตลิน:
classSomeFragment : Fragment(R.layout.some_layout) {
//Lazy initialization means bind() won't be called until "binding" is referenced.
private val binding by lazy { SomeLayoutBinding.bind(view) }
override fun onViewCreated(view: View, savedInstanceState: Bundle?){
super.onViewCreated(view, savedInstanceState)
//Once this method is called, you can start using the binding.
}
}
ชวา:
publicclassSomeFragmentextendsFragment{
private SomeLayoutBinding binding = null;publicSomeFragment(){
super(R.layout.some_layout);
}
@Override
publicvoidonViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
//Initialize the binding.
binding = SomeLayoutBinding.bind(view);
}
}
การสร้างอินสแตนซ์ด้วยมุมมองใหม่
คลาสการรวมยังสามารถดูแลการขยายเลย์เอาต์ให้กับคุณได้
คอตลิน:
val binding = SomeLayoutBinding.inflate(layoutInflater /* should be a LayoutInflater instance */)
ชวา:
SomeLayoutBinding binding = SomeLayoutBinding.inflate(layoutInflater /* should be a LayoutInflater instance */);
วิธีการนี้มีประโยชน์ทั้งในส่วนของแฟรกเมนต์และกิจกรรม
หนึ่ง ตัวอย่างแฟรกเมนต์ จะมีลักษณะดังนี้
คอตลิน:
classSomeFragment : Fragment() {
private val binding by lazy { SomeLayoutBinding.inflate(LayoutInflater.from(requireContext())) }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?){
//The "root" of the binding class is the root of its layout.
return binding.root
}
}
ชวา:
publicclassSomeFragmentextendsFragment{
private SomeLayoutBinding binding = null;
@Override
publicvoidonCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
//Initialize the binding.
binding = SomeLayoutBinding.inflate(inflater);
//The "getRoot()" method of the binding class returns the root of the layout.
return binding.getRoot();
}
}
หนึ่ง ตัวอย่างกิจกรรม จะมีลักษณะดังนี้
คอตลิน:
classSomeActivity : AppCompatActivity() {
private val binding by lazy { SomeLayoutBinding.inflate(layoutInflater) }override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
//This is equivalent to calling "setContentView(R.layout.some_layout)" but allows use of the binding class.
setContentView(binding.root)
}
}
ชวา:
publicclassSomeActivityextendsAppCompatActivity{
private SomeLayoutBinding binding = null;@Override
protectedvoidonCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//Instantiate the binding.
binding = SomeLayoutBinding.inflate(getLayoutInflater());
//This is equivalent to calling "setContentView(R.layout.some_layout)" but allows use of the binding class.
setContentView(binding.getRoot());
}
}
การอ้างอิงมุมมอง
ตอนนี้เมื่อ View Binding Class ได้รับการตั้งค่าและพร้อมใช้งานแล้ว ก็ถึงเวลาใช้งานจริง
สมมติว่าเนื้อหาของ some_layout.xml
มีลักษณะดังต่อไปนี้:
android:
...>
android:
...
/>
android:
...
/>
android:
...>
android:
...
/>
LinearLayout>
LinearLayout>
มี ID มากมายให้อ้างอิงในโค้ด แต่ตราบใดที่คุณมีคลาสที่มีผลผูกพัน การอ้างอิงก็จะเป็นเรื่องง่าย
ใน Kotlin มุมมองจะถูกอ้างอิงโดยตัวแปรที่ตรงกับ ID โดยมีการเปลี่ยนแปลงบางอย่าง ขีดล่างจะถูกลบออกและสตริงผลลัพธ์จะเป็นแบบคาเมล เช่น เพื่ออ้างอิง some_frame_layout
จากโค้ด คุณจะใช้ binding.someFrameLayout
. ที่ someFrameLayout
ตัวแปรจะเป็นอินสแตนซ์ของ FrameLayout
val someFrameLayout: FrameLayout = binding.someFrameLayout
ใน Java Views จะถูกอ้างอิงโดยเมธอด getter ที่ตรงกับ ID ซึ่งมีรูปแบบคล้ายกับ Kotlin เช่น เพื่ออ้างอิง some_frame_layout
คุณจะใช้ binding.getSomeFrameLayout()
. วิธีการนี้จะส่งคืนอินสแตนซ์ของ FrameLayout
FrameLayout someFrameLayout = binding.getSomeFrameLayout();
การอ้างอิงมุมมองยังถูกทำให้เรียบในการผูกข้อมูลด้วย การอ้างอิง inner_imageview
ก็เหมือนกับการอ้างอิง some_frame_layout
.
บทสรุป
อย่างที่ฉันแน่ใจว่าคุณจะเห็นได้ว่า View Binding ใน Android นั้นใช้งานง่ายและใช้งานง่าย ในหลายกรณีการใช้งานง่ายกว่า findViewById()
.
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการใช้งาน View Binding พร้อมด้วยตัวอย่างบางส่วน ตรวจสอบเอกสารอย่างเป็นทางการของ Google.