I'm Learning Android Development with Kotlin and I was learning about Custom ListView where we need to make an Adapter. But when made it, I found something in the code about which I'm confused what is it and why it is used there. While using LayoutInfalter.from(), in from() method I have to pass the context but whose context to pass as I the whole code different context has been passed.
package com.example.myapplication
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
import androidx.core.content.ContextCompat
class ItemAdapter(val items : Array<Item>) : BaseAdapter() {
override fun getCount(): Int {
return items.size
}
override fun getItem(position: Int): Item {
return items[position]
}
override fun getItemId(position: Int): Long {
return items[position].ItemName.hashCode().toLong()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val conView = LayoutInflater.from(parent?.context).inflate(R.layout.list_item, parent, false)// in from() why parent?.context is passed.
val ItemNames : TextView = conView.findViewById(R.id.item_name)
val ItemPrice : TextView = conView.findViewById(R.id.item_price)
ItemNames.text = getItem(position).ItemName
ItemPrice.text = "₹ ${getItem(position).ItemPrice.toString()}"
val item = getItem(position)
if(item.isFav){
conView.setBackgroundColor(ContextCompat.getColor(conView.context, R.color.teal_200)) // in this line why we pass conView.context, why not something else as we usually do by passing 'this'.
}else{
conView.setBackgroundColor(ContextCompat.getColor(conView.context, R.color.white)) // in this line why we pass conView.context, why not something else as we usually do by passing 'this'.
}
return conView
}
}
In the code we have passed two different context,
- parent?.context
- conView.context why we needed two context and how to figure out whose context to pass?
I have marked the line on my code where i'm not able to understand the context as comment.
CodePudding user response:
LayoutInflater used to instantiates a layout XML file into its corresponding View objects. You can't use Views directly. By passing content, It will return LayoutInflater object from which you can access the child views and by using dot(.) operator to access View's properties.
parent?.context used to get whole xml root view as object. while, conView.context used to provide access to particular "conView" properties members.
CodePudding user response:
The Context can contain all kinds of information about the current state of the app. The part of the Context that is important for Views and their related classes are the resources.
Also keep in mind that Activity is its own Context. It is a subclass of Context. So when you are writing code inside your Activity class, you can pass this
as the Context parameter. Inside other classes, you cannot use this
as the context if those classes are not subclasses of Context. (Almost the only classes you'll ever work with that are subclasses of Context are Activity, Service, and Application.)
The XML file doesn't have context, but when you call setContentView
in your Activity, the Activity passes itself as the context parameter for each view that it's inflating, so all of the Views in the layout are referencing the same Activity instance as their own context
.
The Activity's resources will have the currently selected language for String resources, and the correct layouts for the current screen orientation, etc. That's what Views are using the Context for.
Inside your adapter, it is fine to use parent.context
. A child View should always be using the same context as its parent. Incidentally, the parent's context will actually be the Activity that was used to inflate the view layout in setContentView
.
It's also fine to use conview.context
, since this will be the same Context instance that was passed in a previous call to this same function.
You should change the function signature so parent
is not nullable, because it can never be null. This makes it easier to work with. You won't need the ?.
null-safe call so your code will be clearer.
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {