skip to Main Content

I have a RecyclerView and am trying to pass the location from my adapter back to the mainactivity without success so far .

I think the code in the adapter is passing the data back is working, but unfortunately I can’t work out how to set the initialisation in the onCreate in the MainActivity to work? I’m not certain how to call this using “lazy” (ie “private val itemAdapter by lazy” in the mainactivity”)?

I am getting frustrated solving this so any help appreciated.

MainActivity.kt

class MainActivity : AppCompatActivity(), ItemAdapter.OnItemClickListener {
private val itemAdapter by lazy {
    ItemAdapter { position: Int, item: Item ->
        Toast.makeText(this@MainActivity, "Pos ${position}", Toast.LENGTH_LONG).show()
        item_list.smoothScrollToPosition(position)
    } }
private val possibleItems = listOf(
    Item("Plane 1", R.drawable.ic_airplane),
    Item("Car 2", R.drawable.ic_car),
    Item("Meals 3", R.drawable.ic_food),
    Item("Fuel 4", R.drawable.ic_gas),
    Item("Home 5 ", R.drawable.ic_home)
)
fun onImageClick(imageData: String?) {
    // handle image data
}
override fun onCreate(savedInstanceState: Bundle?) {
    var position: Int
    val thisitem: Item
    var thisunit: Unit
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    //       var itemAdapter = ItemAdapter(possibleItems)
    //       var thisitemAdapter = ItemAdapter((position, thisitem) -> thisunit)
    //          Toast.makeText(this@MainActivity, "Pos ${position}", Toast.LENGTH_LONG).show()
    //          item_list.smoothScrollToPosition(position) //CAN'T GET THIS TO COMPILE 
    item_list.initialize(itemAdapter)
    itemAdapter.setOnItemClickListener(this) // Added this
    ItemSnapHelper().attachToRecyclerView(item_list)
    item_list.setViewsToChangeColor(listOf(R.id.list_item_background, R.id.list_item_text))
    item_list.scrollToPosition(Int.MAX_VALUE/2)
    itemAdapter.setItems(possibleItems)
}
override
public fun getAdapterPosition(position : Int ){
    Toast.makeText(this,"this is toast message" + position,Toast.LENGTH_SHORT).show()
}
private fun getLargeListOfItems(): List<Item> {
    val items = mutableListOf<Item>()
    (0..40).map { items.add(possibleItems.random()) }
    return items
}
}
data class Item(
    val title: String,
    @DrawableRes val icon: Int
)

ItemAdapter.kt

class ItemAdapter(val itemClick: (position:Int,item:Item) -> Unit) : RecyclerView.Adapter<ItemViewHolder>() {
private var items: List<Item> = listOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder =
    ItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false))
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
    val pos = position % items.size
    holder.bind(items[pos])        // bind the actual item
    Log.d("xx position= ", pos.toString())
}
override fun getItemCount(): Int = Int.MAX_VALUE
fun setItems(newItems: List<Item>) {
    items = newItems
    notifyDataSetChanged()
}
lateinit var listener: OnItemClickListener

public interface OnItemClickListener {
    fun getAdapterPosition(position : Int )
}
public fun setOnItemClickListener(listener: OnItemClickListener) {
    this.listener= listener
}
}
class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
    fun bind(item: Item) {
        view.list_item_text.text = "${item.title}"
        view.list_item_icon.setImageResource(item.icon)
     }
 }

2

Answers


  1. you have a listener so you can write like this

    class MainActivity : AppCompatActivity(), ItemAdapter.OnItemClickListener {
    
    private lateinit var itemAdapter: ItemAdapter
    
    private val possibleItems = listOf(
        Item("Plane 1", R.drawable.ic_airplane),
        Item("Car 2", R.drawable.ic_car),
        Item("Meals 3", R.drawable.ic_food),
        Item("Fuel 4", R.drawable.ic_gas),
        Item("Home 5 ", R.drawable.ic_home)
    )
    fun onImageClick(imageData: String?) {
        // handle image data
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        var position: Int
        val thisitem: Item
        var thisunit: Unit
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    
        itemAdapter = ItemAdapter()
        itemAdapter.listener = this
        item_list.initialize(itemAdapter)
    
    
        ItemSnapHelper().attachToRecyclerView(item_list)
        item_list.setViewsToChangeColor(listOf(R.id.list_item_background, R.id.list_item_text))
        item_list.scrollToPosition(Int.MAX_VALUE/2)
        itemAdapter.setItems(possibleItems)
    }
    override
    public fun getAdapterPosition(position : Int ){
        Toast.makeText(this,"this is toast message" + position,Toast.LENGTH_SHORT).show()
    }
    private fun getLargeListOfItems(): List<Item> {
        val items = mutableListOf<Item>()
        (0..40).map { items.add(possibleItems.random()) }
        return items
    }
    }
    

    ItemAdapter.kt

     class ItemAdapter : RecyclerView.Adapter<ItemViewHolder>() {
        private var items: List<ClipData.Item> = listOf()
        var listener: OnItemClickListener? = null
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder = ItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false))
    
        override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
            holder.bind(items[position], position)
        }
    
        override fun getItemCount(): Int = Int.MAX_VALUE
        fun setItems(newItems: List<ClipData.Item>) {
            items = newItems
            notifyDataSetChanged()
        }
    }
    
    class ItemViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
        fun bind(item: ClipData.Item, position: Int) {
    
            view.list_item_text.text = "${item.title}"
            view.list_item_icon.setImageResource(item.icon)
    
            view.list_item_text.setOnClickListener {
                listener?.getAdapterPosition(position)
            }
        }
    }
    
    interface OnItemClickListener {
        fun getAdapterPosition(position: Int)
    }
    
    Login or Signup to reply.
  2. Instead of creating an interface you can also pass a lambda function as a callback to the Adapter.

    Basic structure will be like this:

    class MainActivity: AppCompatActivity() {
        
        override fun onCreate(savedInstanceState: Bundle?) {
            ...
            val itemAdapter = ItemAdapter { position ->
                // do whatever you wish with this position
            }
            recyclerView.adapter = itemAdapter
            ...
        }
    }
    
    class ItemAdapter(private val onClick: (Int) -> Unit) {
    
        ...
    
        inner class ItemViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
    
            fun bind(item: ClipData.Item, position: Int) {
                ...
                view.setOnClickListener {
                    onClick(position)
                }
            }
        }
    
    }
    

    If you don’t want to create ItemViewHolder as an inner class, you can accept the onClick lambda in its constructor and pass it there from onCreateViewHolder.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search