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
you have a listener so you can write like this
ItemAdapter.kt
Instead of creating an interface you can also pass a lambda function as a callback to the Adapter.
Basic structure will be like this:
If you don’t want to create
ItemViewHolder
as an inner class, you can accept theonClick
lambda in its constructor and pass it there fromonCreateViewHolder
.