- Published on
Android View System: Scrolling View Knowledge
- Authors
- Name
- Dan Tech
- @dan_0xff
The next piece of knowledge after you understand the Android Activity Lifecycle is the Android View System. In this series of articles on this topic, you will learn how to use the most commonly used View types in an Android application: ScrollView, RecyclerView, ViewPager2, LinearLayout, ConstraintLayout, CardView, ...
Let's goooo!
ScrollView
This is the most basic Scrolling View in Android. It supports you to scroll the content inside it. Usually, we will put a LinearLayout inside the ScrollingView and, depending on whether the purpose is to scroll vertically or horizontally, we will set the LinearLayout accordingly.
ViewPager2
Why ViewPager2 and not ViewPager?
Before ViewPager2, ViewPager was used extensively for almost 10 years. However, in recent years, ViewPager has been improved and optimized. Google's Android developers introduced ViewPager2 as a significant upgrade to ViewPager. This upgrade helps the Fragments inside ViewPager to be reused better, while reducing the lag effect when dragging and switching Fragments inside ViewPager2 compared to ViewPager.
Using ViewPager2 is also very simple.
private val viewPagerAdapter = MainPagerAdapter(this)
fun setupViewPager2() {
binding.mainViewPager.adapter = viewPagerAdapter
}
fun updateViewPager2(data: List) {
viewPagerAdapter.update(data)
}
class MainPagerAdapter(fragment: Fragment)
: FragmentStateAdapter(fragment) {
private val data: MutableList = mutableListOf()
fun update(list: List){
data.clear()
data.addAll(list)
notifyDataSetChanged()
}
override fun createFragment(position: Int): Fragment {
return Fragment.newInstance() // just an example, will show more in real use case
}
override fun getItemCount(): Int {
return data.size
}
}
In reality, we rarely use the update function of ViewPager2 multiple times. Usually, the update function of MainPagerAdapter is only called once when the program starts.
In the practical exercise, we will have a more specific demo application.
RecyclerView
Problem Statement
To talk about RecyclerView, it may take up to 10 articles to fully exploit the advantages and disadvantages of this type of View in Android. However, that is an advanced issue. Within the scope of this article, we will learn and understand the uses of RecyclerView and how to optimize the use of this type of View in the application development process.
Problem statement: Your Phonebook application has 1000 phone numbers and you need to display them in a vertical ScrollView. You can easily create a ScrollView and create 1000 Child Views inside to represent 1000 phone numbers. Everything goes smoothly until you suddenly realize that these 1000 Child Views take up too much memory. At any given time, you can only see about 10 phone numbers, but it costs Memory to store 1000 Child Views. This is a huge waste.
Solution of Android RecyclerView
RecyclerView is a solution to this difficulty. True to its name, RecyclerView, when used, will create a certain number of Child Views and as you scroll to see other Items, the Views that are pulled out of the User's visible area will be Recycled and used for Drawing the Views that are about to appear in the User's Scrolling direction.
To do this, the RecyclerView architecture needs a class called RecyclerView.Adapter. This Adapter class will be responsible for managing which types of Views need to be created, and managing how to Recycle Child Views as well as optimizing the Drawing process. Simply put, RecyclerView.Adapter is a class dedicated to deciding which View will be Recycled and Drawn onto the RecyclerView during use.
private val myAdapter by lazy { MyAdapter() }
fun setupRecyclerView() {
binding.recyclerView.adapter = myAdapter
}
fun updateRecyclerView(dataList: List) {
myAdapter.submitList(dataList)
}
class MyAdapter() : RecyclerView.Adapter() {
private val dataList: MutableList = mutableListOf()
fun submitList(data: List) {
dataList.clear()
dataList.addAll(data)
notifyDataSetChanged()
}
}
Android RecyclerView Sample Code Tutorial
In addition to the simple coding method above, we can use a new feature of RecyclerView. Adapter called ListAdapter. ListAdapter has its own management method, which helps to optimize the processing between updates. However, it still has some limitations compared to the traditional method.
data class SimpleUIModel(val number: String)
class MyAdapter : ListAdapter(differCallback) {
companion object {
val differCallback = object : DiffUtil.ItemCallback() {
override fun areItemsTheSame(oldItem: SimpleUIModel, newItem: SimpleUIModel): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: SimpleUIModel, newItem: SimpleUIModel): Boolean {
return oldItem == newItem
}
override fun getChangePayload(oldItem: SimpleUIModel, newItem: SimpleUIModel): Any {
return newItem
}
}
}
inner class SimpleViewHolder(val viewBinding: ItemSimpleViewHolderBinding) :
RecyclerView.ViewHolder(viewBinding.root) {
fun bind(simpleUI: SimpleUIModel) {
log.d("NotesVH bind: $simpleUI")
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return SimpleViewHolder(
ItemSimpleViewHolderBinding.inflate(
LayoutInflater.from(parent.context),
parent, false
)
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as? SimpleViewHolder)?.bind(getItem(position))
}
}
Detailed explanations of the logic in ListAdapter as well as the basic Adapter will be in the video course with complete information and examples. I hope this tutorial will motivate you to learn Android programming better on your own.