Rustam
Rustam

Reputation: 59

How to apply data from RecyclerView to MainActivity

I have horizontal Recyclerview with images. I want when I click the image on Recyclerview to set the background of my MainActivity imageView. I don't know how to apply from Recyclerview to my Mainactivity class.

This is my MainActivity class:

 class MainActivity : AppCompatActivity() {
    
        private lateinit var recyclerView: RecyclerView
        private var imagesUrl: ArrayList<String> = ArrayList()
        
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            takeCapture.setOnClickListener(takePictureListener)
    
            getImagesUrl()
        }
    
        private fun getImagesUrl() {
            imagesUrl.apply {
                add("https://image.freepik.com/free-photo/dark-studio-background_1258-14.jpg")
                add("https://i.pinimg.com/236x/e7/f6/47/e7f647952cc3f7381d0707965e422db0.jpg")
                add("https://image.freepik.com/free-vector/abstract-dark-black-background-studio-room-with-sportlight_1035-18643.jpg")
                add("https://thumbs.dreamstime.com/z/empty-black-studio-room-dark-background-abstract-texture-product-showcase-spotlight-gallery-136762537.jpg")
            }
            initRecyclerView()
        }
    
        private fun initRecyclerView() {
            recyclerView = findViewById(R.id.recyclerView)
            recyclerView.apply {
                layoutManager = LinearLayoutManager(applicationContext, LinearLayoutManager.HORIZONTAL, false)
                adapter = ImageAdapter(applicationContext, imagesUrl)
            }
        }
    
        private val takePictureListener = View.OnClickListener {
            val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            startActivityForResult(intent, 0)
        }
    
        override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            super.onActivityResult(requestCode, resultCode, data)
    
            val bitmap = data!!.extras!!.get("data") as Bitmap
            val resized = Bitmap.createScaledBitmap(bitmap, 700, 550, true)
            imageView.setImageBitmap(resized)
        }

}

And my RecyclerView Adapter class

class ImageAdapter(private val context: Context, private val list: ArrayList<String>) : RecyclerView.Adapter<ImageAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.image_recycler, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        Picasso.get().load(list[position]).into(holder.circleImageView)
    }

    override fun getItemCount(): Int = list.size

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val circleImageView : CircleImageView = itemView.circleImage
    }
}

Upvotes: 0

Views: 1028

Answers (2)

Aditya Tyagi
Aditya Tyagi

Reputation: 431

Here I have used callback approach with interfaces where on the click of any item in your recyclerView you'll be getting a callback and you can do alteration accordingly with that callback in your activity.

Your MainActivity class will become something like this:-

class MainActivity : AppCompatActivity():ImagesAdapter.OnItemClickListener {

    private lateinit var recyclerView: RecyclerView
    private var imagesUrl: ArrayList<String> = ArrayList()
    private lateinit var imageAdapter:ImageAdapter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        takeCapture.setOnClickListener(takePictureListener)

        getImagesUrl()
    }

    private fun getImagesUrl() {
        imagesUrl.apply {
            add("https://image.freepik.com/free-photo/dark-studio-background_1258-14.jpg")
            add("https://i.pinimg.com/236x/e7/f6/47/e7f647952cc3f7381d0707965e422db0.jpg")
            add("https://image.freepik.com/free-vector/abstract-dark-black-background-studio-room-with-sportlight_1035-18643.jpg")
            add("https://thumbs.dreamstime.com/z/empty-black-studio-room-dark-background-abstract-texture-product-showcase-spotlight-gallery-136762537.jpg")
        }
        initRecyclerView()
    }

    private fun initRecyclerView() {
        recyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)        //Your activity's context
        imageAdapter = ImageAdapter(this, imagesUrl)        //Your activity's context
        recyclerView.adapter = imageAdapter
        imageAdapter.setOnItemClickListener(this)
    }

    private val takePictureListener = View.OnClickListener {
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        startActivityForResult(intent, 0)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        val bitmap = data!!.extras!!.get("data") as Bitmap
        val resized = Bitmap.createScaledBitmap(bitmap, 700, 550, true)
        imageView.setImageBitmap(resized)
    }

    override fun onItemClicked(backroundImage:String){
        Picasso.get().load(backroundImage).into(imageView)         //Here pass the image view of your activity class
    }

}

And your adapter class changes will be something like this:-

class ImageAdapter(private val context: Context, private val list: ArrayList<String>) : RecyclerView.Adapter<ImageAdapter.ViewHolder>() {
   
    private lateinit var onItemClickListener:OnItemClickListener

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.image_recycler, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        Picasso.get().load(list[position]).into(holder.circleImageView)
    }

    override fun getItemCount(): Int = list.size

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val circleImageView : CircleImageView = itemView.circleImage
        itemView.setOnItemClickListener{
            if (::onItemClickListener.isInitialized)
                onItemClickListener.onItemClicked(list[adapterPosition])
        }
    }


    interface OnItemClickListener{
        fun onItemClicked(background:String)
    }

    fun setOnItemClickListener(onItemClickListener:OnItemClickListener){
        this.onItemClickListener = onItemClickListener
    }
}

Upvotes: 3

Egor
Egor

Reputation: 40193

The simplest solution would be to pass a reference to MainActivity into the ImageAdapter:

// Change ImageAdapter's constructor to
class ImageAdapter(
  private val context: Context, 
  private val list: ArrayList<String>,
  private val activity: MainActivity
)

// In MainActivity
adapter = ImageAdapter(applicationContext, imagesUrl, this)

Add a public method to MainActivity that changes the background:

fun changeBackground(drawable: Drawable) {
  // Change MainActivity's background
}

And call that method inside ImageAdapter:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
  ...
  activity.changeBackground()
}

You might also want to decouple ImageAdapter from MainActivity and pass a callback function, e.g. (Drawable) -> Unit, into ImageAdapter instead. In this case, MainActivity will pass a lambda to ImageAdapter's constructor, and ImageAdapter will call that lambda inside an onClickListener.

Upvotes: 0

Related Questions