Search code examples
androidandroid-intentandroid-activitykotlinandroid-recyclerview

Kotiln: pass data from adapter to activity


I try to pass my data from the adapter to my other activity with a putExtra but when I click on an item in my list to move to my second activity, no data is retrieved and the default text I put in is not displayed. another way to do? or What do I miss about it? Here my code :

My onBindViewHolder:

override fun onBindViewHolder(holder: AlbumsListViewHolder, position: Int) {
    val AlbumsData = albumsData!![position]
    holder.albumsName.text = AlbumsData.title

    Glide.with(holder.itemView)
        .load(AlbumsData.cover)
        .transition(DrawableTransitionOptions.withCrossFade())
        .into(holder.coverImage)

    holder.itemView.setOnClickListener {
        val intent = Intent(holder.itemView.context, TracksActivity::class.java)
        //listener?.onClick(AlbumsData)
        intent.putExtra("dd", "ff")
        holder.itemView.context.startActivity(intent)
    }
}

My second Activity:

class TracksActivity: AppCompatActivity(), TracksView {

    private var albumsAdapter: AlbumsAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
        super.onCreate(savedInstanceState, persistentState)
        setContentView(R.layout.activity_tracks)

        //albumsAdapter = findViewById(R.id.trackslist_recycleview)
        val msg = intent.getStringExtra("dd")
        Log.d("dd", "${msg}")
    }
}

Solution

  • Method 1 :

    You can use callback First of all, define a callback in your adapter like this :

        interface CallbackInterface {   
            fun passResultCallback(message: String)
        }
    

    Then initialize the callback interface in your adapter :

    class YourAdapter(private val callbackInterface:CallbackInterface) :
        RecyclerView.Adapter<CurrencyListAdapter.ViewHolder>() {
    .
    .
    .
    }
    

    Then use the callback method from the interface inside your onBindViewHolder() like this :

    holder.itemView.setOnClickListener {
            //Set your codes about intent here
            callbackInterface.passResultCallback("Your message")
    }
    

    And finally, implement your callback method in your activity like this :

    class TracksActivity: AppCompatActivity(), TracksView , YourAdapterName.CallbackInterface {
    
        private var albumsAdapter: AlbumsAdapter? = null
    
        override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
            super.onCreate(savedInstanceState, persistentState)
            setContentView(R.layout.activity_tracks)
        }
    
      override fun passResultCallback(message: String) {
             //message is "ff"
        }
    }
    

    UPDATE:

    Method 2 :

    If you dont use callback, as you wrote just change your activity to this :

    class TracksActivity: AppCompatActivity(), TracksView {
    
        private var albumsAdapter: AlbumsAdapter? = null
    
        override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
            super.onCreate(savedInstanceState, persistentState)
            setContentView(R.layout.activity_tracks)
    
            var bundle : Bundle? = intent.extras
            var message = bundle!!.getString("dd") 
            Log.d("dd", "${message}")
        }
    }
    

    UPDATE : December 26, 2019

    Method 3 : KOTLIN BASE

    We can pass a fun to adapter and get data from it like this :

    In our adapter :

    class YourAdapter(private val clickListener: (yourData: YourData) -> Unit) :
        RecyclerView.Adapter<YourAdapter.ViewHolder>() {
    
    //YourData like String
    
    //And we have onCreateViewHolder like this 
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.your_item, parent,false),
            clickListener
        )
    
    //And we have ViewHolder class like this 
    
      inner class ViewHolder(itemView: View, private val clickListener: (yourData: YourData) -> Unit) :
            RecyclerView.ViewHolder(itemView) {
    .
    .
    .
         init {
                initClickListeners()
            }
    
    //And pass data here with invoke
    
    
            private fun initClickListeners() {
                itemView.setOnClickListener { clickListener.invoke(yourData) }
            }
    }
    

    In our fragment or activity we can get data with this way :

    YourAdapter { yourData ->
                // we can use yourData here
                }