hi im currently using kotlin for my android project,as per instruction,i was told to make an apps that has recycleview to show list item and intent when you click on one of the list shown. but i have this error when i want to run the app,the error was "No value passed for parameter 'ListUserAdapter'" here is my code
ListUserAdapter.kt
class ListUserAdapter(private val ListUserAdapter: ArrayList<User>) : RecyclerView.Adapter<ListUserAdapter.ListViewHolder>() {
private lateinit var onItemClickCallBack: OnItemClickCallBack
fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallBack) {
this.onItemClickCallBack = onItemClickCallback
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
val view: View = LayoutInflater.from(parent.context).inflate(R.layout.row_user, parent, false)
return ListViewHolder(view)
}
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
val (name, username) = ListUserAdapter[position]
holder.tvName.text = name
holder.tvUserName.text= username
holder.itemView.setOnClickListener {
onItemClickCallBack.onItemClicked(ListUserAdapter[holder.adapterPosition])
}
}
override fun getItemCount(): Int = ListUserAdapter.size
class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var tvName: TextView = itemView.findViewById(R.id.tv_username)
var tvUserName: TextView = itemView.findViewById(R.id.tv_name)
}
interface OnItemClickCallBack {
fun onItemClicked(data : User)
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var adapter: ListUserAdapter
private lateinit var dataName: Array<String>
private lateinit var dataUsername: Array<String>
private lateinit var dataLocation: Array<String>
private lateinit var dataRepo: Array<String>
private lateinit var dataCompany: Array<String>
private lateinit var dataFollowers: Array<String>
private lateinit var dataFollowing: Array<String>
private lateinit var dataPhoto: TypedArray
private var users = arrayListOf<User>()
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setAdapter()
prepare()
addItem()
}
private fun setAdapter() {
adapter = ListUserAdapter() //error in here
with(binding) {
rvList.adapter = adapter
rvList.layoutManager =
GridLayoutManager(this@MainActivity, 2, GridLayoutManager.HORIZONTAL, false)
rvList.setHasFixedSize(true)
}
adapter.setOnItemClickCallback(object : ListUserAdapter.OnItemClickCallBack{
override fun onItemClicked(user: User) {
val intent = Intent(this@MainActivity, DetailActivity::class.java)
intent.putExtra(DetailActivity.KEY_USER, user)
startActivity(intent)
}
})
}
private fun prepare() {
dataName = resources.getStringArray(R.array.name)
dataUsername = resources.getStringArray(R.array.username)
dataPhoto = resources.obtainTypedArray(R.array.avatar)
dataLocation = resources.getStringArray(R.array.location)
dataRepo = resources.getStringArray(R.array.repository)
dataCompany = resources.getStringArray(R.array.company)
dataFollowers = resources.getStringArray(R.array.followers)
dataFollowing = resources.getStringArray(R.array.following)
}
private fun addItem() {
for (position in dataName.indices) {
val user = User(
dataUsername[position],
dataName[position],
dataLocation[position],
dataCompany[position],
dataRepo[position],
dataFollowers[position],
dataFollowing[position],
dataPhoto.getResourceId(position, -1)
)
users.add(user)
}
}
}
DetailActivity.kt
class DetailActivity : AppCompatActivity() {
private lateinit var binding: ActivityDetailBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDetailBinding.inflate(layoutInflater)
setContentView(binding.root)
setData()
}
private fun setData() {
val dataUser = intent.getParcelableExtra<User>(KEY_USER) as User
with(binding) {
Glide.with(root)
.load(dataUser.photo)
.circleCrop()
.into(ivDetailAvatar)
}
}
companion object {
const val KEY_USER = "key_user"
}
}
CodePudding user response:
You're just forgetting the constructor parameter :)
Your adapter class needs to receive a ArrayList
of User
to be instantiated, you already have it in your Activity
, you just need to pass it as the constructor parameter :)
I would also rename the parameter name to something like users
or usersList
instead of `ListUserAdapter but because currently it is misleading, since this parameter is not an adapter, it is a list of users.
Just change the line with error to
adapter = ListUserAdapter(users)
But I think it is best for you to first call prepare()
and addItem()
and then instantiate your adapter. Or you can instantiate your adapter, but also create a addItems
function, since it is a best practice for adapters.
fun addItems(users: List<User>) {
this.ListUserAdapter.addAll(users)
notifyDataSetChanged()
}
and use it after setting everything up inside onCreate
doing something like
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setAdapter()
prepare()
addItem()
adapter.addItems(users)
}
but you could probably reorganize these methods to improve readability as well, but it will work :)
CodePudding user response:
just you need to replace adapter = ListUserAdapter() //error in here
with adapter = ListUserAdapter(users)
then your problem solve