I'm trying to update the below recycler view to show the new data that input from the form in the second activity. However, its only showing the original list that I had in there. What am I doing wrong here?
Here is the main activity:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
var workoutList = mutableListOf(
Workout("a","d","d","d"),
Workout("a","d","d","d"),
Workout("a","d","d","d")
)
val adaptor = WorkoutAdaptor(workoutList)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnNext.setOnClickListener {
Intent(this, SecondActivity::class.java).also {
startActivity(it)
}
}
binding.recyclerView.adapter = adaptor
binding.recyclerView.layoutManager = LinearLayoutManager(this)
}
override fun onRestart() {
super.onRestart()
var workout = intent.getSerializableExtra("EXTRA_WORKOUT") as Workout
workoutList.add(workout)
adaptor.notifyDataSetChanged()
}
}
Here is the adapter:
class WorkoutAdaptor (
var workouts: List<Workout>
) : RecyclerView.Adapter<WorkoutAdaptor.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val workoutCardBinding = WorkoutCardBinding.inflate(
LayoutInflater.from(parent.context), parent, false)
return ViewHolder(workoutCardBinding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(workouts[position])
}
override fun getItemCount(): Int {
return workouts.size
}
inner class ViewHolder(private val workoutCardBinding: WorkoutCardBinding) :
RecyclerView.ViewHolder(workoutCardBinding.root) {
fun bind(workout: Workout) {
workoutCardBinding.tvWorkoutCard.text = workout.toString()
}
}
}
And here is the activity where I get the workout object from:
class SecondActivity : AppCompatActivity() {
private lateinit var binding: ActivitySecondBinding
lateinit var spWorkoutsPosition: String
lateinit var spIncrementsPosition: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySecondBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.spWorkoutTypes.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
spWorkoutsPosition = p0?.getItemAtPosition(p2) as String
}
override fun onNothingSelected(p0: AdapterView<*>?) {
}
}
binding.spIncrements.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(adapterView: AdapterView<*>?, view: View?, position: Int, id: Long) {
spIncrementsPosition = adapterView?.getItemAtPosition(position) as String
}
override fun onNothingSelected(p0: AdapterView<*>?) {
}
}
binding.btnSave.setOnClickListener {
val workoutName = binding.tvWorkoutName.text.toString()
val workoutType = spWorkoutsPosition.toString()
val workoutIncrement = spIncrementsPosition.toString()
val workoutRestTime = binding.etRestTime.text.toString()
val workout = Workout(workoutName, workoutType, workoutIncrement, workoutRestTime)
Intent(this, MainActivity::class.java).also {
it.putExtra("EXTRA_WORKOUT", workout)
startActivity(it)
}
}
}
}
As #John Doe commented you should probably use ActivityResultLauncher. refer here.
and as for the update issue the recommended way of implementing recyclerView's adapter is androidx.recyclerview.widget.ListAdapter. The ListAdapter handles addition and removal without the need to redraw the entire view, and even animate those changes.
here's the implementation for your adapter:
class WorkoutAdaptor :
ListAdapter<Workout, WorkoutAdaptor.ItemViewHolder>(DiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
return ItemViewHolder(
ItemAutocompleteSearchResultBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
holder.bind(position)
}
inner class ItemViewHolder(val binding: ItemAutocompleteSearchResultBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(position: Int) {
binding.apply {
workoutCardBinding.tvWorkoutCard.text = getItem(position).toString()
}
}
}
private class DiffCallback : DiffUtil.ItemCallback<Workout>() {
override fun areContentsTheSame(oldItem: Workout, newItem: Workout): Boolean {
return oldItem == newItem
}
override fun areItemsTheSame(oldItem: Workout, newItem: Workout): Boolean {
return oldItem.param1 == newItem.param1 &&
oldItem.param2 == newItem.param2 &&
oldItem.param3 == newItem.param3 &&
oldItem.param4 == newItem.param4
}
}
}
then you only have to call,
adapter.submitList(workoutList)
after you update the workoutList and the ListAdapter handles the rest.
and also call the adapter.submitList() in onStart() or onResume() methods.
Related
I'm new to Kotlin. I have a MainActivity and a list view inside.
When an item is clicked in the list view, I want to update a textView inside MainActivity.
However because data should be passed from ListView to MainActivity, I did something weird:
MainActivity.kt:
data class Country(val imgRes:Int, val name:String)
class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding
private val data = arrayListOf<Country>()
val imgRes = intArrayOf()
val data1 = arrayOf()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
for(i in imgRes.indices) {
val country = Country(imgRes[i], data1[i])
data.add(country)
}
val adapter = RecyclerAdapter(data, object:RecyclerAdapter.OnItemClickListener {
override fun onItemClick(v: View, pos: Int) {
binding.textView.text = (v as TextView).text
}
})
binding.recycler1.adapter = adapter
binding.recycler1.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
}
}
ListView.kt:
class RecyclerAdapter(private val dataSet:List<Country>, private val listener:OnItemClickListener) : RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
public interface OnItemClickListener {
fun onItemClick(v:View, pos:Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = RowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun getItemCount(): Int {
return dataSet.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(position)
}
inner class ViewHolder(val binding: RowBinding) : RecyclerView.ViewHolder(binding.root) {
val rowImageView = binding.rowImageView
val rowTextView = binding.rowTextView
init {
binding.root.setOnClickListener {
listener.onItemClick(rowTextView, adapterPosition)
}
}
fun bind(pos: Int) {
with(binding) {
rowImageView.setImageResource(dataSet[pos].imgRes)
rowTextView.text = dataSet[pos].name
}
}
}
}
I declared interface(OnItemClickListener) at ListView.kt and redefine it at MainActivity.kt.
It works fine but is there any better way to do this?
You can use higher order functions instead of interface.
Define this function top of your Adapter:
var onClick: ((text: String) -> Unit)? = null
in ViewHolder:
binding.root.setOnClickListener {
onClick?.invoke(dataSet[position].text)
}
in MainActivity:
adapter.onClick = { name ->
binding.textView.text = name
}
You can also find more information about higher orders in here
<include android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/yourlayout" />
Try this in your Adapter:
var itemClickListener: ((position: Int, name: String) -> Unit)? = null
Bindviewholder:
itemClickListner.invoke(1,"anyvalue")
in Activity:
adapter.itemClickListener = {
position, name ->
Toast.makeText(requireContext(),"position is $position name is $name ",Toast.LENGTH_SHORT).show()
}
in Adapter:
private var mListener: OnItemClickListener,
interface OnItemClickListener {
fun onClick(position: Int, routerArray: ArrayList<Router>)
}
binding.yourView.setOnClickListener {
mListener.onClick(adapterPosition, routerArray)
}
in Activity:
override fun onClick(position: Int, yourArray: ArrayList<Model>) {
binding.textView.text = yourArray[position].text
}
I want to add an object from my RecyclerView to database by clicking on its icon. I use MVVM pattern, so I should add a object in Fragment. I have 2 callbacks and second one should add an object to database when by clicking. How can I get object so as to use it in viewModel.saveWord() method in adapter callback. Or I should do it anywhere else?
RecyclerView Adapter:
class SearchDefAdapter(
private var infoListener: OnItemClickListener,
private var addListener: OnItemClickListener
):
ListAdapter<Def, SearchDefViewHolder>(differCallback) {
interface OnItemClickListener {
fun onItemClick(position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchDefViewHolder {
return SearchDefViewHolder(
SearchWordCardBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
),
addListener,
infoListener
)
}
override fun onBindViewHolder(holder: SearchDefViewHolder, position: Int) {
holder.bind(getItem(position))
}
}
RecyclerView ViewHolder:
class SearchDefViewHolder(
private val binding: SearchWordCardBinding,
addListener: SearchDefAdapter.OnItemClickListener,
infoListener: SearchDefAdapter.OnItemClickListener
): RecyclerView.ViewHolder(binding.root) {
fun bind(data: Def) {
with (binding) {
searchCardTv.text = "${data.text} - ${data.tr[0].text}"
}
}
init {
binding.addSearchCard.setOnClickListener {
addListener.onItemClick(adapterPosition)
}
binding.infoSearchCard.setOnClickListener {
infoListener.onItemClick(adapterPosition)
}
}
}
RecyclerView differ callback:
val differCallback = object : DiffUtil.ItemCallback<Def>() {
override fun areItemsTheSame(oldItem: Def, newItem: Def): Boolean {
return oldItem.text == newItem.text
}
override fun areContentsTheSame(oldItem: Def, newItem: Def): Boolean {
return oldItem == newItem
}
}
Adapter initialization in fragment:
searchDefAdapter = SearchDefAdapter(
object : SearchDefAdapter.OnItemClickListener {
override fun onItemClick(position: Int) {
if (!translationsList.isNullOrEmpty()){
val bundle = Bundle()
bundle.putStringArray(INFO_BUNDLE_ID, translationsList[position])
val wordFragment = WordFragment()
wordFragment.arguments = bundle
parentFragmentManager.beginTransaction().apply {
replace(R.id.searchFragment, wordFragment)
commit()
}
}
}
},
object : SearchDefAdapter.OnItemClickListener {
override fun onItemClick(position: Int) {
//viewModel.saveWord()
}
}
)
Change your callback parameter from position to your item type.
interface OnItemClickListener {
fun onItemClick(def: Def)
}
//...
class SearchDefViewHolder(
private val binding: SearchWordCardBinding,
addListener: SearchDefAdapter.OnItemClickListener,
infoListener: SearchDefAdapter.OnItemClickListener
): RecyclerView.ViewHolder(binding.root) {
private lateinit var def: Def
fun bind(data: Def) {
with (binding) {
searchCardTv.text = "${data.text} - ${data.tr[0].text}"
}
def = data
}
init {
binding.addSearchCard.setOnClickListener {
addListener.onItemClick(def)
}
binding.infoSearchCard.setOnClickListener {
infoListener.onItemClick(def)
}
}
}
Then in your Fragment, your listeners are easier to define and directly give you the item to write to database.
My problem is that when I write MyListAdapter.currentList.isEmpty() the value is true even tho the list is NOT EMPTY! (I can see it in my view and in my database). What am I doing wrong, why is the value true even tho it should be false?
Fragment
#AndroidEntryPoint
class ShoppingCartFragment(
private val cacheMapper: ShopCacheMapper
) : Fragment(R.layout.fragment_shopping_cart), ShoppingCartListAdapter.OnItemClickListener {
private val shoppingCartViewModel: ShoppingCartViewModel by viewModels()
private val shoppingCartBinding: FragmentShoppingCartBinding by viewBinding()
#Inject lateinit var shoppingCartAdapter: ShoppingCartListAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
bindObjects()
observeList()
hideBtnIfListEmpty()
toast("LISTE IST EMPTY: ${shoppingCartAdapter.currentList.isEmpty()}")
}
private fun observeList() {
shoppingCartViewModel.productList.observe(viewLifecycleOwner) {
shoppingCartAdapter.submitList(it)
}
}
private fun bindObjects() = with(shoppingCartBinding) {
adapter = shoppingCartAdapter.apply { clickHandler(this#ShoppingCartFragment) }
viewModel = shoppingCartViewModel
lifecycleOwner = viewLifecycleOwner
}
override fun forwardCardClick(productCacheEntity: ProductCacheEntity) {
val product = cacheMapper.mapFromEntity(productCacheEntity)
val action = ShoppingCartFragmentDirections.actionShoppingCartFragmentToShopItemFragment(product)
findNavController().navigate(action)
}
override fun fordwardBtnIncreaseClick(id: Int) {
shoppingCartViewModel.increaseProductQuantityById(id)
}
override fun fordwardBtnDecreaseClick(id: Int) {
shoppingCartViewModel.decreaseProductQuantityById(id)
}
override fun forwardBtnDeleteClick(id: Int) {
shoppingCartViewModel.deleteProductById(id)
}
override fun onDestroyView() {
requireView().findViewById<RecyclerView>(R.id.rv_shopping_cart).adapter = null
super.onDestroyView()
}
// here lies the problem
private fun hideBtnIfListEmpty() {
if (shoppingCartAdapter.currentList.isEmpty()) shoppingCartBinding.shoppingCartBtn.root.visibility = View.INVISIBLE
else if (shoppingCartAdapter.currentList.isNotEmpty()) shoppingCartBinding.shoppingCartBtn.root.visibility = View.VISIBLE
}
}
ListAdapter
#FragmentScoped
class ShoppingCartListAdapter #Inject constructor() : ListAdapter<ProductCacheEntity, ShoppingCartListAdapter.ProductViewHolder>(Companion) {
private lateinit var clickListener: OnItemClickListener
companion object: DiffUtil.ItemCallback<ProductCacheEntity>() {
override fun areItemsTheSame(oldItem: ProductCacheEntity, newItem: ProductCacheEntity): Boolean = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: ProductCacheEntity, newItem: ProductCacheEntity): Boolean = oldItem == newItem
}
inner class ProductViewHolder(val binding: ShoppingCartListItemBinding): RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ShoppingCartListItemBinding.inflate(layoutInflater, parent, false)
return ProductViewHolder(binding).also {
with(binding) {
ivProduct.setOnClickListener { clickListener.forwardCardClick(binding.product!!) }
tvTitle.setOnClickListener { clickListener.forwardCardClick(binding.product!!) }
btnIncrease.setOnClickListener { clickListener.fordwardBtnIncreaseClick(binding.product!!.id) }
btnDecrease.setOnClickListener { clickListener.fordwardBtnDecreaseClick(binding.product!!.id) }
btnDelete.setOnClickListener { clickListener.forwardBtnDeleteClick(binding.product!!.id) }
}
}
}
override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
val currentProduct = getItem(position) ?: return
holder.binding.product = currentProduct
holder.binding.btnDecrease.isEnabled = currentProduct.quantity > 1
holder.binding.executePendingBindings()
}
interface OnItemClickListener {
fun forwardCardClick(productCacheEntity: ProductCacheEntity)
fun fordwardBtnIncreaseClick(id: Int)
fun fordwardBtnDecreaseClick(id: Int)
fun forwardBtnDeleteClick(id: Int)
}
fun clickHandler(clickEventHandler: OnItemClickListener) {
this.clickListener = clickEventHandler
}
}
Layout
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_shopping_cart"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="#id/shopping_cart_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/headline"
app:recyclerview_adapter_stableID="#{adapter}"
tools:listitem="#layout/shopping_cart_list_item" />
Bindingadapter (app:recyclerview_adapter_stableID)
#BindingAdapter("recyclerview_adapter_stableID")
fun setRecyclerViewAdapterWithStableId(view: RecyclerView, adapter: RecyclerView.Adapter<*>) {
view.run {
this.setHasFixedSize(true)
this.adapter = adapter
}
}
You are calling ListAdapter.Currentlist.isEmpty() within hideBtnIfListEmpty() too early before making sure that the list is ready and submitted by observeList()
You can call it after you submit the list to the adapter:
private fun observeList() {
shoppingCartViewModel.productList.observe(viewLifecycleOwner) {
shoppingCartAdapter.submitList(it)
hideBtnIfListEmpty()
}
}
I am trying to implement the function onClick in the CustomAdapter into a button so that I can call an action. I want to make it so that when the user clicks on the recycler item, the onClick function calls openTopSheet() that is from MainActivity which brings down the top sheet. In essence, how can I make it so that onClick can perform a method from MainActivity? Any help would be appreciated
CustomAdapter.kt
class CustomAdapter(val modelList: List<Model>, val context: Context) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as ViewHolder).bind(modelList.get(position));
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return ViewHolder(layoutInflater.inflate(R.layout.row_item, parent, false))
}
override fun getItemCount(): Int {
return modelList.size;
}
lateinit var mClickListener: ClickListener
fun setOnItemClickListener(aClickListener: ClickListener) {
mClickListener = aClickListener
}
interface ClickListener {
fun onClick(pos: Int, aView: () -> Unit)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
var r = MainActivity()
init {
itemView.setOnClickListener(this)
}
override fun onClick(p0: View?) {
r.openTopSheet()
}
fun bind(model: Model): Unit {
itemView.txt.text = model.name
itemView.sub_txt.text = model.version
val id = context.resources.getIdentifier(model.name.toLowerCase(Locale.ROOT), "drawable", context.packageName)
itemView.img.setBackgroundResource(id)
}
}
}
MainActivity.kt
open class MainActivity : AppCompatActivity(), BottomSheetRecyclerViewAdapter.ListTappedListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.home_page)
}
fun openTopSheet() {
topSheetBehavior.state = TopSheetBehavior.STATE_EXPANDED
topSheetBehavior.setTopSheetCallback(object : TopSheetBehavior.TopSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float, isOpening: Boolean?) {
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
}
})
}
}
In ViewHolder:
bind(model: Model, openTopSheet: ()->Unit)
itemView.button.setOnClickListener{
openTopSheet.invoke()
}
In adapter:
class CustomAdapter(
val modelList: List<Model>,
val context: Context,
val openTopSheet: ()->Unit)
)
(holder as ViewHolder).bind(modelList.get(position), openTopSheet);
In Activity:
val adapter = CustomAdapter(listOf(), this, { openTopSheet() } )
And you need to add openTopSheet method in activity.
I have a recyclerView with 10 names and in this activity is possible search for name. With a click in a name the activity moves to another(with help Intents to move for DetailsActivity). It possible make this because in adapter, i have a function that give the position that the user have clicked. But when put a word in menu search this functional gives the position 1 (the real position of name, in exactally moment).
I can send in function in adpter for example, the id of name? What is the correct way to make this?
MainActivity.kt
class MainActivity : AppCompatActivity(), PeopleInStarWarsAdapter.OnNoteListener {
private lateinit var mainViewModel: MainViewModel
private var listDataPeople = ArrayList<DataPeople>()
private lateinit var dataPeopleAdapter: PeopleInStarWarsAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainViewModel = ViewModelProvider
.AndroidViewModelFactory
.getInstance(application)
.create(MainViewModel::class.java)
//iniciar ViewModel
mainViewModel.init(this)
mainViewModel.getList().observe(this, Observer{ it ->
if(it != null){
listDataPeople = it
dataPeopleAdapter.submitList(listDataPeople)
}
else{
Toast.makeText(this, "Something is wrong!", Toast.LENGTH_SHORT).show()
}
})
initRecyclerView(listDataPeople)
}
private fun initRecyclerView(listDataPeople : ArrayList<DataPeople>) {
recycler_view.layoutManager = LinearLayoutManager(this)
dataPeopleAdapter = PeopleInStarWarsAdapter(listDataPeople, this)
recycler_view.adapter = dataPeopleAdapter
}
override fun onNoteClick(position: Int){
val intent = Intent(this, DetailsActivity::class.java)
intent.putExtra(BuildConfig.POSITION, position)
startActivity(intent)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main_menu, menu)
val manager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
val searchItem = menu?.findItem(R.id.search)
val searchView = searchItem?.actionView as SearchView
searchView.setSearchableInfo(manager.getSearchableInfo(componentName))
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String): Boolean {
searchView.clearFocus()
searchView.setQuery("", false)
searchItem.collapseActionView()
Log.v("Information", "Looking for $query")
mainViewModel.checkMatch(query, this#MainActivity)
return true
}
override fun onQueryTextChange(newText: String): Boolean {
Log.v("Information", "$newText")
return false
}
})
return true
}
}
PeopleInStarWarsAdapter.kt
class PeopleInStarWarsAdapter(listDataPeople: ArrayList<DataPeople>, onNoteListener: OnNoteListener) : RecyclerView.Adapter<RecyclerView.ViewHolder>(){
var listDataPeople = ArrayList<DataPeople>()
private var mOnNoteListener : OnNoteListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.layout_list_item, parent,
false)
)
}
override fun getItemCount(): Int {
return listDataPeople.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ViewHolder -> {
holder.ViewHolder(listDataPeople[position], mOnNoteListener)
}
}
}
fun submitList(dataPeopleList: ArrayList<DataPeople>) {
this.listDataPeople = dataPeopleList
notifyDataSetChanged()
}
class ViewHolder constructor(itemView: View): RecyclerView.ViewHolder(itemView), View.OnClickListener {
private val textViewName : TextView = itemView.textView_name
var onNoteListener: OnNoteListener? = null
fun ViewHolder(dataPeople: DataPeople, onNoteListener: OnNoteListener) {
val name = dataPeople.name
this.textViewName.text = name
this.onNoteListener = onNoteListener
itemView.setOnClickListener(this)
}
override fun onClick(v: View?) {
onNoteListener?.onNoteClick(adapterPosition)
}
}
interface OnNoteListener {
fun onNoteClick(position: Int)
}
init {
this.listDataPeople = listDataPeople
mOnNoteListener = onNoteListener
}
}
You should send position to ViewHolder .
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ViewHolder -> {
holder.ViewHolder(listDataPeople[position], mOnNoteListener,position)
}
}
}
Then pass this value into onNoteClick()
fun ViewHolder(dataPeople: DataPeople, onNoteListener: OnNoteListener,position: Int) {
val name = dataPeople.name
this.textViewName.text = name
this.onNoteListener = onNoteListener
itemView.setOnClickListener(this)
}
override fun onClick(v: View?) {
onNoteListener?.onNoteClick(position)
}