🎨 UI – Views और Layouts · Lesson 12
View Binding
findViewById की problem
Kotlin
// ❌ findViewById – easy to use the wrong id or wrong type val tvMessage = findViewById<TextView>(R.id.tvMessage) val btnHello = findViewById<Button>(R.id.btnHelo) // typo → crash only at runtime
findViewById
- हर view के लिए एक line
- गलत id → runtime पर crash
- गलत type cast → crash
- null लौटा सकता है
View Binding
- सारे views एक object में तैयार
- गलत id → compile error
- सही type अपने आप
- Null-safe
Step 1: View Binding enable करें
Kotlin DSL – app/build.gradle.kts
// app/build.gradle.kts
android {
// ...
buildFeatures {
viewBinding = true
}
}
// then: File → Sync Project with Gradle FilesNames कैसे बनते हैं
| Layout file | Binding class |
|---|---|
| activity_main.xml | ActivityMainBinding |
| fragment_notes.xml | FragmentNotesBinding |
| item_note.xml | ItemNoteBinding |
| View id | Property |
|---|---|
| @+id/tvMessage | binding.tvMessage |
| @+id/btn_save | binding.btnSave (snake_case → camelCase) |
| (root view) | binding.root |
Step 2: Activity में use
Kotlin – MainActivity.kt
package com.example.helloapp
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.helloapp.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var count = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater) // 1. inflate
setContentView(binding.root) // 2. show its root view
binding.btnHello.setOnClickListener { // 3. use ids as properties
count++
binding.tvMessage.text = "Namaste! You clicked $count times"
}
}
}Fragment में use
Kotlin – NotesFragment.kt
class NotesFragment : Fragment() {
private var _binding: FragmentNotesBinding? = null
private val binding get() = _binding!! // valid only between onCreateView and onDestroyView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentNotesBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tvTitle.text = "My notes"
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null // avoid memory leaks
}
}RecyclerView adapter में use
Kotlin – NoteAdapter.kt
class NoteAdapter(private val items: List<String>) :
RecyclerView.Adapter<NoteAdapter.VH>() {
class VH(val binding: ItemNoteBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
VH(ItemNoteBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun onBindViewHolder(holder: VH, position: Int) {
holder.binding.tvTitle.text = items[position]
}
override fun getItemCount() = items.size
}Included layouts और layout ignore करना
XML + Kotlin
<!-- activity_main.xml -->
<include
android:id="@+id/header"
layout="@layout/layout_header" />
// Kotlin – the include becomes a nested binding
binding.header.tvHeaderTitle.text = "Dashboard"
<!-- to skip generating a binding class for a layout -->
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
tools:viewBindingIgnore="true" />आम गलतियाँ
setContentView(R.layout.activity_main)भी करना और binding भी inflate करना → दो copies; listeners अदृश्य copy पर लगते हैं।setContentView(binding.root)use करें।- Gradle sync भूलना → "Unresolved reference: databinding"।
- Fragment में onDestroyView के बाद (जैसे देर से आए callback में)
bindinguse करना → crash;_binding != nullcheck करें।
सारांश
viewBinding = trueenable करें; हर layout कोXxxBindingclass मिलती है।- Activity:
inflate(layoutInflater)+setContentView(binding.root)। - Fragment: nullable
_binding,onDestroyViewमें clear।
✅ Practice
अपने BMI calculator को findViewById से View Binding में बदलिए। गिनिए कितनी lines कम हुईं।
अक्सर पूछे जाने वाले प्रश्न (FAQ)
क्या View Binding और Data Binding एक ही हैं?
नहीं। View Binding सिर्फ़ views के references बनाता है। Data Binding XML में expressions भी लिखने देता है। View Binding आसान और build में तेज़ है, और ज़्यादातर projects यही use करते हैं।
Fragments में _binding और binding क्यों?
Fragment अपने view से ज़्यादा देर ज़िंदा रह सकता है। onDestroyView में _binding = null करने से पुराने views छूट जाते हैं और memory leak नहीं होता; बीच में binding non-null getter है।
क्या View Binding app को धीमा करता है?
नहीं। Binding class build time पर बनती है और layout एक बार inflate करती है — findViewById जितनी ही तेज़।
