setOnClickListener in adapter with kotlin - android

I just started learning Kotlin
i would like to start a new activitys from a RecyclerView with Kotlin.
for example :
if user tap on first item go to activity1
if user tap on secend item go to activity2
and...
i did make adaptor and adaptor will show in a feragment and there isnt any issue with start adaptor
my adaptor code:
package com.mysfk.android
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class ReviewAdaptor() :RecyclerView.Adapter<ReviewAdaptor.ViewHolder>() {
private var titles = arrayOf("بخاری","دریچه","فن و پد","آبیاری","فن چرخشی","مه پاش","پرده")
private var details = arrayOf("جزیئات تست","جزیئات تست","جزیئات تست","جزیئات تست","جزیئات تست","جزیئات تست","جزیئات تست")
private var images = intArrayOf(R.drawable.icon,R.drawable.icon,R.drawable.icon,R.drawable.icon,R.drawable.icon,R.drawable.icon,R.drawable.icon)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReviewAdaptor.ViewHolder {
val v =LayoutInflater.from(parent.context).inflate(R.layout.card_review,parent,false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ReviewAdaptor.ViewHolder, position: Int) {
holder.tittleItem.text = titles[position]
holder.ditealItem.text = details[position]
holder.imageItem.setImageResource(images[position])
}
override fun getItemCount(): Int {
return titles.size
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var imageItem : ImageView
var tittleItem : TextView
var ditealItem :TextView
init {
imageItem = itemView.findViewById(R.id.imageReview)
tittleItem = itemView.findViewById(R.id.titleReview)
ditealItem = itemView.findViewById(R.id.detReview)
itemView.setOnClickListener{
}
}
}
}
and this is my items:

In ReviewAdaptor declare a listener:
private lateinit var itemClickListener: View.OnClickListener
public fun setItemClickListener(listener: View.OnClickListener) {
itemClickListener = listener
}
In your ViewHolder:
itemView.tag = this
itemView.setOnClickListener(itemClickListener)
And in your fragment:
reviewAdaptor.setItemClickListener{
val viewHolder: RecyclerView.ViewHolder = it.tag as RecyclerView.ViewHolder
val position = viewHolder.adapterPosition
// Open activity by postion
}

Related

Firebase remove child recyclerview Kotlin

I need to remove child from Firebase after onClick from RecyclerView Adapter.
I have something like this:
Firebase database is
recyclerview is
My biggest problem is not sure how to get the "key" of the child node from the recyclerview.
I have been stuck on this supposedly simple thing for about 3 days so hopefully any help is appreciated.
package com.cpg12.findingfresh.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.cpg12.findingfresh.R
import com.cpg12.findingfresh.database.ShoppingList
import com.google.firebase.database.FirebaseDatabase
class ShoppingListAdapter : RecyclerView.Adapter<ShoppingListAdapter.ShoppingListViewHolder>() {
private val shoppingList = ArrayList<ShoppingList>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShoppingListViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.shopping_list_item, parent, false)
/** References the node to which market data is stored**/
val databaseReference = FirebaseDatabase.getInstance().getReference("Users")
return ShoppingListViewHolder(itemView)
}
override fun onBindViewHolder(holder: ShoppingListAdapter.ShoppingListViewHolder, position: Int) {
val currentItem = shoppingList[position]
holder.sListItem.text = currentItem.shoppingItem
}
override fun getItemCount(): Int {
return shoppingList.size
}
fun updateShoppinglist(shoppingList: List<ShoppingList>){
this.shoppingList.clear()
this.shoppingList.addAll(shoppingList)
notifyDataSetChanged()
}
class ShoppingListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
val sListItem : TextView = itemView.findViewById(R.id.ShoppingItemTV)
override fun onClick(v: View?) {
databaseReference.child(marketName).setValue(markets).child(key).setValue("")
}
}
}

Type mismatch: inferred type is RecyclerAdapter but RecyclerView.Adapter<RecyclerView.ViewHolder>? was expected in RecyclerView

I was learning about RecyclerViews and tried making one after watching this tutorial.
Everything was going great until the very end when I got an error when connecting my adapter to my MainActivity.
The error I got in my MainActivity.kt was:
Type mismatch: inferred type is RecyclerAdapter but RecyclerView.Adapter<RecyclerView.ViewHolder>? was expected
Error is on line 22
This is my MainActivity.kt
package com.example.testing
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rvTest = findViewById<RecyclerView>(R.id.rvTest)
layoutManager = LinearLayoutManager(this)
rvTest.layoutManager = layoutManager
adapter = RecyclerAdapter()
rvTest.adapter = adapter
}
}
And this is my RecyclerAdapter
package com.example.testing
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class RecyclerAdapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
private var Title = arrayOf("Cosmopolitan", "Vodka Sprite")
private var Image = intArrayOf(R.drawable.ic_launcher_foreground, R.drawable.ic_launcher_background)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.rv, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
holder.itemTitle.text = Title[position]
holder.itemImage.setImageResource(Image[position])
}
override fun getItemCount(): Int {
return Title.size
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var itemImage: ImageView
var itemTitle: TextView
init {
itemImage = itemView.findViewById(R.id.imageView)
itemTitle = itemView.findViewById(R.id.textView)
}
}
}
You are extending the variable with the Extension RecyclerView.Adapter<RecyclerView.ViewHolder>() instead of the class RecyclerAdapter.
Replace
private var adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>? = null
with
private lateinit var adapter : RecyclerViewAdapter ?= null
In your MainActivity.kt
private var adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>? = null
The datatype for adapter variable is wrong
Change it to something like this
private var adapter: RecyclerAdapter? = null
Also instead of making it of type nullable, you can instead change to lateinit & make it non nullable type as it would be initialised inside onCreate
private lateinit var adapter: RecyclerAdapter
change
private var adapter: RecyclerView.Adapter<RecyclerView.ViewHolder>()
to
private var adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>

How to change the value of Alpha when item is clicked inside RecyclerView?

I am not able to figure out how to change the value of alpha when clicked on the item of the RecyclerView . I want to change the value of alpha from 1 to 0.5 .
Below is the Adapter Class for the same .
package GiftClass
import LeaderboardClass.LeaderboardAdapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.gearsrun.www.R
import kotlinx.android.synthetic.main.item_gift.view.*
class GiftAdapter(private val giftList: List<Gift>) : RecyclerView.Adapter<GiftAdapter.GiftViewHolder>() {
private lateinit var mlistener : onItemClickListener
interface onItemClickListener{
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener){
mlistener = listener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GiftViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_gift,parent,false)
return GiftViewHolder(itemView,mlistener)
}
override fun onBindViewHolder(holder: GiftViewHolder, position: Int) {
val currentItem = giftList[position]
holder.item_img.setImageResource(currentItem.imageResource)
holder.item_price.text = currentItem.price
holder.item_soldNum.text = currentItem.sold_num
holder.item_medal.text = currentItem.medal_num
}
override fun getItemCount() = giftList.size
class GiftViewHolder(itemView: View,listener:onItemClickListener) : RecyclerView.ViewHolder(itemView){
val item_img:ImageView = itemView.item_img
val item_price : TextView = itemView.price
val item_soldNum : TextView = itemView.sold_num
val item_medal : TextView = itemView.medal_num
init {
itemView.setOnClickListener {
listener.onItemClick(absoluteAdapterPosition)
itemView.alpha = 0.5f
}
}
}
}
Added References / Suggestion are appreciated
In the onClickListener , you can get the property itemView.alpha and adjust the alpha values as per your needs

RecyclerView onitemClickListener in Kotlin

I am new on kotlin .Getting error on click listner on line holder.initilise(chapterlist.get(position),clickListener)
Error shows on word clickListener . Kindly help me to resolve my issue. i want to click on one view and transfer on another recyclerView. These list shows chapters i want to go on topics list and every chapter has its own topics.holder.initilise(chapterlist.get(position),clickListener) is commented in the code and it just shows the list which i extract from backend
Code :
import android.content.Context
import android.view.Display
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class CustomeAdapter(val ctx: Context, var clickListener: Int, var chapterlist:ArrayList<Model>) : RecyclerView.Adapter<ViewHolder>() {
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val user : Model = chapterlist[position]
holder?.textViewName?.text=user.name
holder?.textViewChapter?.text=user.desc
// holder.initilise(chapterlist.get(position),clickListener) //(getting error on clickListener)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent?.context).inflate(R.layout.row,parent,false)
return ViewHolder(v)
}
override fun getItemCount(): Int {
return chapterlist.size
}
}
class ViewHolder(itemView: View) :RecyclerView.ViewHolder(itemView){
val textViewName = itemView.findViewById(R.id.textView) as TextView
val textViewChapter = itemView.findViewById(R.id.textView2) as TextView
fun initilise(list: Model, action:OnChapterClick){
textViewName.text=list.name
textViewChapter.text=list.desc
itemView.setOnClickListener{
action.onItemClick(list,adapterPosition)
}
}
}
interface OnChapterClick {
fun onItemClick(list: Model,position: Int )
}
Follow below steps:
Step - 1: You have to implements OnChapterClick in your MainActivity2
class MainActivity2: AppCompatActivity, OnChapterClick {
....
override fun onItemClick(list: Model, position: Int ) {
//Implement your logic here
}
}
Step - 2: Change your CustomeAdapter's constructor to accept OnChapterClick instead of int
class CustomeAdapter(val ctx: Context, var clickListener: OnChapterClick, var chapterlist:ArrayList<Model>) : RecyclerView.Adapter<ViewHolder>() {
....
}
Step - 3: Initialize the adapter with this instead of R.layout.row like below:
val adapter = CustomeAdapter(applicationContext, this#MainActivity2, chapterlist)
Your clickListener is defined to be an Int:
var clickListener: Int
That's probably wrong, since integers can't listen to clicks. It should probably be:
var clickListener: OnChapterClick

Implement On Click Listener in ViewHolder With Access To Associated Item

I have heard it is good practice to implement the onClickListener inside of the ViewHolder. However, I am not sure how to access the item that is associated with the ViewHolder inside of the onClickListener.
For example:
import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import kotlinx.android.synthetic.main.post.view.*
import rstudio.vedantroy.swarm.MainActivity.Companion.TAG
class PostAdapter(private val items : List<Post>, private val contex: Context) : RecyclerView.Adapter<MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(contex).inflate(R.layout.post, parent, false))
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.bodyContent.text = items[position].content
}
}
class MyViewHolder(view: View): RecyclerView.ViewHolder(view), View.OnClickListener {
override fun onClick(v: View?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
val bodyContent : TextView = view.bodyContent
}
How do I access items, and how do I find out the current index of the ViewHolder?
I looked at this example: Recyclerview(Getting item on Recyclerview), but there was no explanation of where mDataSource comes from.
Personally what I find is a good solution is to set the OnClickListener within the onBindViewHolder.
For example,
// ... adapter class ...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.view.apply {
bodyContent.text = items[position].content
setOnClickListener {
// TODO Handle onClick
}
}
}
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view)
Also I find just storing the view within the ViewHolder makes it very easy to access any elements within the layout.
I managed to implement this behavior by moving the location of PostViewHolder. However, I am not sure if inner class will break something.
package rstudio.vedantroy.swarm
import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.cardview.widget.CardView
import kotlinx.android.synthetic.main.post.view.*
import rstudio.vedantroy.swarm.MainActivity.Companion.TAG
class PostAdapter(private val items : List<Post>, private val contex: Context) : RecyclerView.Adapter<PostAdapter.PostViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostViewHolder {
return PostViewHolder(LayoutInflater.from(contex).inflate(R.layout.post, parent, false))
}
override fun getItemCount() = items.size
override fun onBindViewHolder(holder: PostViewHolder, position: Int) {
holder.bodyContent.text = items[position].content
}
inner class PostViewHolder(view: View): RecyclerView.ViewHolder(view) {
val bodyContent : TextView = view.bodyContent
init {
view.apply {
setOnClickListener {
isClickable = false
Log.d(TAG, "Clicked!")
}
}
}
}
}

Categories

Resources