Reputation: 27
I want to create a new intent/activity when the user clicks on a cardview respectively and i was wondering how does one do it in kotlin. i noticed most tutorials are in java and i'm a student who did not learn java.
package com.example.ttshfypj.adapters
import androidx.fragment.app.Fragment
import android.view.View
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.ttshfypj.data_class.medications
import android.widget.ImageView
import android.widget.TextView
import com.example.ttshfypj.R
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.list_medication.view.*
class medicationAdapter (val medicationlist: ArrayList<medications>) : RecyclerView.Adapter<medicationAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_medication, parent, false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return medicationlist.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val medicationgroup: medications = medicationlist[position]
holder?.medicationnamevar?.text = medicationgroup.medicineN
holder?.medicationschedulevar?.text = medicationgroup.MedicineTime
val imagemedicine = holder?.itemView?.medicationimageview
Picasso.get().load(medicationgroup.MedicineImage).into(imagemedicine)
}
class ViewHolder(itemView: View) :RecyclerView.ViewHolder(itemView) {
val medicationnamevar = itemView.findViewById(R.id.medicationname) as TextView
val medicationschedulevar = itemView.findViewById(R.id.medicationschedule) as TextView
}
}
Upvotes: 0
Views: 2370
Reputation: 3930
You can create an interface
for Item Click Listener
like
interface MyItemClickListener{
fun itemClick(position: Int)
}
Now you should pass context to the constructor
of your adapter
.
class medicationAdapter (val medicationlist: ArrayList<medications>, var context: Context) : RecyclerView.Adapter<medicationAdapter.ViewHolder>() {...}
and create an instance of MyItemClickListener
inside your adapter
// create instance of MyItemClickListener
private val clickListener = context as MyItemClickListener
And setclick listener
on your view inside the onCreateViewHolder
.
modify your adapter
like this
class medicationAdapter (val medicationlist: ArrayList<medications>, var context: Context) : RecyclerView.Adapter<medicationAdapter.ViewHolder>() {
// create instance of MyItemClickListener
private val clickListener = context as MyItemClickListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
var inflater = LayoutInflater.from(parent.context)
var v = inflater.inflate(R.layout.list_medication, parent, false)
var viewHolder = ViewHolder(v)
// here you set click listener on your item view.
v.setOnClickListener {
clickListener.itemClick(viewHolder.adapterPosition)
}
return viewHolder
}
override fun getItemCount(): Int {
return medicationlist.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val medicationgroup: medications = medicationlist[position]
holder?.medicationnamevar?.text = medicationgroup.medicineN
holder?.medicationschedulevar?.text = medicationgroup.MedicineTime
val imagemedicine = holder?.itemView?.medicationimageview
Picasso.get().load(medicationgroup.MedicineImage).into(imagemedicine)
}
class ViewHolder(itemView: View) :RecyclerView.ViewHolder(itemView) {
val medicationnamevar = itemView.findViewById(R.id.medicationname) as TextView
val medicationschedulevar = itemView.findViewById(R.id.medicationschedule) as TextView
}
}
And finally, in your activity, you have to implement the MyItemClickListener
interface and override
the itemClick()
like this
class YourActivity: AppCompatActivity(), MyItemClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ....
}
override fun itemClick(position: Int) {
Log.d("TAG","Click Item Position: "+position)
// here you can call your new activity according to your item position.
}
}
Upvotes: 0
Reputation: 1633
If you are using kotlin you can also use method reference where you directly pass a method to be called inside the adapter and you can directly invoke it there.
Activity.kt
Adapter(this::itemClickHandler);
private fun itemClickHandler(int position){
// your logic here
}
Adapter.kt
class Adapater(val itemClickHandler:(Int)->Unit):RecyclerView.Adapter(){
override fun onBindViewHolder(){
//you can invoke it here like this
itemClickHandler.invoke(adapterPosition);
}
}
please refer this full code
MainActivity.kt
package com.example.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val list = mutableListOf<Items>()
for(i in 1..25){
list.add(Items(CHILD,"Child"))
}
with(rvList) {
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = Adapter(list, this@MainActivity::onItemClickHandler)
}
}
private fun onItemClickHandler(position:Int){
Log.d("***","${position}");
//here you can start a new intent to open a new activity on click of item
}
}
The adapter code is as following
package com.example.myapplication
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.layout_child.view.*
import kotlinx.android.synthetic.main.layout_header.view.*
const val HEADER = 1;
const val CHILD = 2;
data class Items(val type: Int, val text: String)
class Adapter(private val list: List<Items>, val itemClickHandler: (Int) -> Unit) :
RecyclerView.Adapter<Adapter.HeaderViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HeaderViewHolder {
val headerView =
LayoutInflater.from(parent.context).inflate(R.layout.layout_header, parent, false)
val headerViewHolder = HeaderViewHolder(headerView)
headerView.setOnClickListener {
itemClickHandler.invoke(headerViewHolder.adapterPosition)
}
return headerViewHolder
}
override fun getItemCount(): Int = list.size
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
holder.onBind(list[position].text)
}
inner class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun onBind(text: String) {
itemView.tvHeader.text = text
}
}
}
Hope this helps and you are able to follow
Upvotes: 1