0

I am using recyclerview in kotlin and I am new to kotlin. I have used button.setOnClickListner method inside this. I want to call a method which is in my mainActivity. How should I do it

I want to call below method which is in mainActivity

fun sendOrder() {

        Log.e("TAG", "SendOrder: "  )

    }

my adapter is below

class CustomAdapterJob(val jobList: ArrayList<JobData>): RecyclerView.Adapter<CustomAdapterJob.ViewHolder>(){
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
    val jobData :JobData = jobList[position]
    holder?.textViewId?.text = jobData.id
    holder?.textViewArea?.text = jobData.area
    holder?.textViewCarType?.text = jobData.carType
    holder?.textViewCarName?.text = jobData.carName
    holder?. textViewDutyHours?.text = jobData.dutyHours
    holder?.textViewWeeklyOff?.text = jobData.weeklyOff
    holder?.textViewDriverAge?.text = jobData.driverAge
    holder?.textViewDriverExperience?.text = jobData.drivingExperience
    holder?.textViewOutstationDays?.text = jobData.outstationDays
    holder?.textViewDutyDetails?.text = jobData.dutyDetails
    holder?.button?.text =jobData.submit
    if(jobData.submit == "true"){
        holder?.button?.setVisibility(View.GONE);
    }

    holder?.button?.setOnClickListener( View.OnClickListener (){
        Log.d("TAG", "job list position : ${jobList[position].id}")
        var id = jobList[position].id
        val p = Pattern.compile("-?\\d+")
        val m = p.matcher(id)
        while (m.find()) {
            System.out.println(m.group())
            sendOrder()
        }
    });

    //To change body of created functions use File | Settings | File Templates.
}

override fun getItemCount(): Int {
     return jobList.size//To change body of created functions use File | Settings | File Templates.
}

override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
    val v=LayoutInflater.from(parent?.context).inflate(R.layout.job_card,parent,false)
    return ViewHolder(v)
    //To change body of created functions use File | Settings | File Templates.
}

class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
    val textViewId = itemView.findViewById<TextView>(R.id.job_id)
    val textViewArea = itemView.findViewById<TextView>(R.id.area)
    val textViewCarType = itemView.findViewById<TextView>(R.id.car_type)
    val textViewCarName = itemView.findViewById<TextView>(R.id.car_name)
    val textViewDutyHours = itemView.findViewById<TextView>(R.id.duty_hours)
    val textViewWeeklyOff = itemView.findViewById<TextView>(R.id.weekly_off)
    val textViewDriverAge = itemView.findViewById<TextView>(R.id.driver_age)
    val textViewDriverExperience = itemView.findViewById<TextView>(R.id.driving_experience)
    val textViewOutstationDays = itemView.findViewById<TextView>(R.id.outstation_days)
    val textViewDutyDetails = itemView.findViewById<TextView>(R.id.duty_details)
    val button = itemView.findViewById<Button>(R.id.apply_job)

}}

now how i have to call sendOrder() method in kotline

5 Answers5

3

Its better you create a listener and pass it to the adapter.

Interface

interface ActivityInteractor {
    fun onInteraction(data: Any?)
}

Implement the interface in your activity

class MainActivity : Activity(), ActivityInteractor {

    override fun onCreate(savedInstance : Bundle) {
        CustomAdapterJob(jobList, this)
    }

    override fun onInteraction(data: Any?) {
        // you can do any activity related tasks here
        sendOrder()
    }
}

Accept the listener in your adapter

class CustomAdapterJob(val jobList: ArrayList<JobData>, val activityInteractor: ActivityInteractor) : RecyclerView.Adapter<CustomAdapterJob.ViewHolder>() {
    holder?.button?.setOnClickListener( View.OnClickListener () {
        Log.d("TAG", "job list position : ${jobList[position].id}")
        var id = jobList[position].id
        val p = Pattern.compile("-?\\d+")
        val m = p.matcher(id)
        while (m.find()) {
            System.out.println(m.group())
            //sendOrder()
            activityInteractor.onInteraction(jobList[position].id)
        }
    });
}

Instead of creating the new interface you can implement onClickListener in the activity and can pass it as a parameter to the adapter class. In the adapter, you can set this onClick listener to your button.

Use kotlin data binding concept to avoid those boilerplate codes like findViewById. please check this link

0

The easiest solution would be to your activity as parameter to your recycler view. Then you could easaly call that function. But obviously this is not a very good aproach, so you should prefer the following.

Create an interface which is implemented by your activity and called instead of the activities method. Within the implementation of the interface function you can call the activity function or whatever you like. As it is implemented by the activity itself you have full access to the whole activity context.

A short example how this could be implemented is already answered here

FreshD
  • 2,914
  • 2
  • 23
  • 34
0

First you need to create a context:

private val context: Context

Then add this context, along with other variables you might have, to your adapter constructor:

class Adapter(..., context: Context)

Inside you while loop:

while (m.find()) {
    System.out.println(m.group)
    if (context is MainActivity)
    {
        (context as MainActivity).SendOrder()
    }
}

Apologies for any syntax error, etc. My Kotlin is still a little rough.

Anuraag Baishya
  • 874
  • 2
  • 11
  • 26
0

you can do like this:

holder?.button?.setOnClickListener( View.OnClickListener (){
    Log.d("TAG", "job list position : ${jobList[position].id}")
    var id = jobList[position].id
    val p = Pattern.compile("-?\\d+")
    val m = p.matcher(id)
    while (m.find()) {
        System.out.println(m.group())
         mySendOrder()
    }
});

public void mySendOrder(){
}

and then in main activity:

yourCustomAdapter = new YourCustomAdapter(){
public void mySendOrder(){
    sendOrder();
  }
}
DB377
  • 403
  • 4
  • 11
  • its saying that yourCustomAdapter does not have companion object and thus must be initialized here @line yourCustomAdapter = new YourCustomAdapter(){ – zeba pathan Mar 14 '18 at 10:49
  • can you show your code where you initialized adapter – DB377 Mar 14 '18 at 12:32
0

In case if you don't need Context or Activity object in your adapter. You can pass callback as parameters. May be something like this

class MyAdapter(private val sendOrder: () -> Unit = {}) : BaseAdapter() {
    fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
        sendOrder()
    }
}

Then implement callback in Activity

fun onCreate(...) {
    recyclerView.adapter = MyAdapter() {
        // Do something
    }
}
babedev
  • 135
  • 3
  • 5
  • what should i write in recyclerView.adapter = MyAdapter() { // Do something }. this will be my sendOrder method?? – zeba pathan Mar 14 '18 at 11:00
  • its saying in activity no value passed for parameter joblist my adapter is class CustomAdapterJob(val jobList: ArrayList, private val sendOrder: () -> Unit = {}): RecyclerView.Adapter(){ – zeba pathan Mar 14 '18 at 11:04