Android SDK: UI Views, RecyclerView & Fragments
View Binding
// build.gradle: viewBinding { enabled = true }
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.textView.text = "Hello"
binding.button.setOnClickListener {
binding.textView.text = "Clicked!"
}
}
}
// In Fragments
class MyFragment : Fragment(R.layout.fragment_my) {
private var _binding: FragmentMyBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
_binding = FragmentMyBinding.bind(view)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null // avoid memory leak
}
}RecyclerView
// Adapter
class ItemAdapter(
private val items: List<String>,
private val onItemClick: (String) -> Unit
) : RecyclerView.Adapter<ItemAdapter.ViewHolder>() {
inner class ViewHolder(val binding: ItemRowBinding) :
RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = ItemRowBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = items[position]
holder.binding.textView.text = item
holder.binding.root.setOnClickListener { onItemClick(item) }
}
override fun getItemCount() = items.size
}
// In Activity/Fragment
binding.recyclerView.apply {
layoutManager = LinearLayoutManager(context)
adapter = ItemAdapter(listOf("Item 1", "Item 2")) { item ->
Toast.makeText(context, item, Toast.LENGTH_SHORT).show()
}
}
// DiffUtil for efficient updates
class ItemDiffCallback(
private val oldList: List<String>,
private val newList: List<String>
) : DiffUtil.Callback() {
override fun getOldListSize() = oldList.size
override fun getNewListSize() = newList.size
override fun areItemsTheSame(old: Int, new: Int) = oldList[old] == newList[new]
override fun areContentsTheSame(old: Int, new: Int) = oldList[old] == newList[new]
}Fragments
// Fragment definition
class DetailFragment : Fragment(R.layout.fragment_detail) {
private val args: DetailFragmentArgs by navArgs() // Navigation Safe Args
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Access args.itemId, args.title
}
companion object {
fun newInstance(id: Int): DetailFragment {
return DetailFragment().apply {
arguments = bundleOf("item_id" to id)
}
}
}
}
// Fragment transactions (without Navigation Component)
supportFragmentManager.commit {
setReorderingAllowed(true)
replace(R.id.fragment_container, DetailFragment.newInstance(42))
addToBackStack(null)
}
// Fragment result API (pass data back to parent fragment)
// Parent fragment:
childFragmentManager.setFragmentResultListener("requestKey", viewLifecycleOwner) { _, bundle ->
val result = bundle.getString("resultKey")
}
// Child fragment:
parentFragmentManager.setFragmentResult("requestKey",
bundleOf("resultKey" to "value")
)Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free