The problem I am facing with the RecyclerView is the data is coming from Server and the API response is getting printed correctly in the console.
but when I am trying to set data in the adapter what is wrong or something is not going correctly with the flow that the data is not being updated on UI.
//This is my adapter class
class DashboardAdapter(val context: Context) : RecyclerView.Adapter<DashBoardHolder>() {
private var transactionList = ArrayList<DashboardData>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DashBoardHolder {
val inflator = LayoutInflater.from(parent.context)
val view = ActivityDashboardDataBinding.inflate(inflator, parent, false)
val viewHolder = DashBoardHolder(view)
return viewHolder
}
override fun onBindViewHolder(holder: DashBoardHolder, position: Int) {
val quickModel = transactionList[position]
holder.tvName.text = quickModel.bookingTitle
}
fun showListItems(dashboardlist: List<DashboardData>?, aboolean: Boolean) {
when {
aboolean -> transactionList.clear()
}
if (dashboardlist != null && !dashboardlist.isEmpty())
this.transactionList.addAll(dashboardlist)
notifyDataSetChanged()
}
override fun getItemCount(): Int {
return transactionList.size
}
}
MyHolderClass
class DashBoardHolder(val binding: ActivityDashboardDataBinding) :
RecyclerView.ViewHolder(binding.root) {
var tvName: TextView = binding.textViewGrandrukName
var tvTime: TextView = binding.tvGrandrukTripDetails
var tvPlace: ImageView = binding.btnGhandruk
var ivRectangle: ImageView = binding.imageView5
}
Similarly,I set the adapter in view section like this way:
//setting adapter in Presenter class
fun setAdapter() {
var layoutmanager: LinearLayoutManager? = LinearLayoutManager(appCompatActivity)
val firstVisiblePosition = layoutmanager!!.findFirstVisibleItemPosition()
binding!!.includesDashboardRecyclerview.rvBookingList.setHasFixedSize(true)
binding!!.includesDashboardRecyclerview.rvBookingList.layoutManager = layoutmanager
binding!!.includesDashboardRecyclerview.rvBookingList.adapter = dashboardAdapter
layoutmanager!!.scrollToPositionWithOffset(firstVisiblePosition, 0)
}
In Presenter Class, calling setAdapter class from presenter like this way
class DashboardPresenter(
private val dashboardView: DashboardView,
private val dashboardModel: DashboardModel
) {
fun onCreateView() {
onClick()
dashboardView.setAdapter()
getDashboardRequest()
}
//calling adpter function here
fun showList(termlist: List<DashboardData>?, aboolean: Boolean) {
(null as DashboardAdapter?)?.showListItems(termlist!!, aboolean)
}
}
I'm not able to understand what is getting wrong here.
(null as DashboardAdapter?)?.showListItems(termlist!!, aboolean)
You are calling showListItems() on the DashboardAdapter as a type not the instance dashboardAdapter. Assuming that dashboardAdapter is a local class field.
Also I guess this type casting is not necessary as you already using the optional ?
So, it can be simplified to:
dashboardAdapter?.showListItems(termlist!!, aboolean)
Assuming that this should be called whenever you retrieve the API response. So, showList() must be called when there's new API data.
Related
This Line is wrong adapter = ItemAdapter(applicationContext,userViewModel.getListUsers())
**Because the adapter parameters context: Context, arrayList: ArrayList (but not MutableLiveData) **
I don’t know what to do about it, and I’m not entirely sure if I am using the LiveData correctly.
My Adapter
class ItemAdapter(var context: Context, private var arrayList: ArrayList<NumberModel>):RecyclerView.Adapter<ItemAdapter.ItemHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder{
val itemHolder = LayoutInflater.from(parent.context).inflate(
R.layout.grid_layout_list_item,
parent,
false
)
return ItemHolder(itemHolder)
}
override fun onBindViewHolder(holder: ItemHolder, position: Int) {
var positionOfNumber:NumberModel = arrayList.get(position)
holder.textOfNumber.text = positionOfNumber.numberOfElement
holder.button.setOnClickListener {
var positionForDelete = holder.adapterPosition
arrayList.removeAt(positionForDelete)
notifyItemRemoved(positionForDelete)
notifyItemRangeChanged(positionForDelete,arrayList.size)
}
}
override fun getItemCount(): Int {
return arrayList.size
}
class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var textOfNumber = itemView.findViewById<TextView>(R.id.numberTextView)
var button:Button = itemView.findViewById(R.id.buttonClick)
}
}
MainActivity
recyclerView = findViewById(R.id.recyclerViewList)
gridLayoutManager = GridLayoutManager(applicationContext,2,LinearLayoutManager.VERTICAL,false)
recyclerView?.layoutManager = gridLayoutManager
recyclerView?.setHasFixedSize(true)
recyclerView?.adapter = adapter
userViewModel.getListUsers().observe(this, Observer {
it?.let {
adapter = ItemAdapter(applicationContext,userViewModel.getListUsers())
}
})
}
ViewModel
class MainActivityViewModel : ViewModel() {
var elementsList: MutableLiveData<ArrayList<NumberModel>> = MutableLiveData()
init {
elementsList.value = setElements()
}
fun getListUsers() = elementsList
private fun setElements() : ArrayList<NumberModel> {
var itemArrayList:ArrayList<NumberModel> = ArrayList()
itemArrayList.add(NumberModel("1"))
itemArrayList.add(NumberModel("2"))
itemArrayList.add(NumberModel("3"))
itemArrayList.add(NumberModel("4"))
itemArrayList.add(NumberModel("5"))
itemArrayList.add(NumberModel("6"))
itemArrayList.add(NumberModel("7"))
itemArrayList.add(NumberModel("8"))
itemArrayList.add(NumberModel("9"))
itemArrayList.add(NumberModel("10"))
return itemArrayList
}
Reason for Because the adapter parameters context: Context, arrayList: ArrayList (but not MutableLiveData) this error.
we are passing the MutableLiveData instead of ArrayList. so we need to pass the ArrayList as the second parameter.
userViewModel.getListUsers().observe(this, Observer {
it?.let { list->
adapter = ItemAdapter(applicationContext,list)
}
})
userViewModel.getListUsers() will give the ArrayList so we can pass this to get the instance of ItemAdapter
instead of passing the applicationContext we can give thisor requireActivity() (will give the MainActivity context),
if we pass the applicationContext, we may lead to a memory leak we have to pass the right context to the object.
My observer is working and it's getting called whenever a new record is entered,
The problem is with recycler view is only showing one record to begin with and it never updates itself to show additional records as a result of save setClickListener.
I can verify in the my database (Room with LiveData) that I've more than one record, there's some problem with the Adapter or the ViewHolder.
P.S. Plus any modifications to how things should be done when it comes to patterns with adapter are most welcome. I hope I got it right.
MainActivity onCreate method
viewModel = ViewModelProvider(this).get(BookViewModel::class.java)
save.setOnClickListener {
val book = Book(UUID.randomUUID().toString(), "author 2", "book 2")
viewModel.insert(book)
}
val bookListAdapter = BookListAdapter(this)
recyclerView.adapter = bookListAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
viewModel.allBooks.observe(this, Observer { books ->
books?.let {
Log.d(TAG, "onCreate: changed")
bookListAdapter.setBooks(books)
}
})
static classes in MainActivity
private class BookListAdapter(private val context: Context): RecyclerView.Adapter<BookListAdapter.BookViewHolder>() {
private var bookList: List<Book> = mutableListOf()
// getting called only once
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookListAdapter.BookViewHolder {
val itemView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false)
return BookViewHolder(itemView)
}
override fun onBindViewHolder(holder: BookListAdapter.BookViewHolder, position: Int) {
val book = bookList[position]
holder.setData(book.author, book.book, position)
}
override fun getItemCount(): Int {
Log.d("inner", "getItemCount: ${bookList.size}") // this return correct size
return bookList.size
}
fun setBooks(it: List<Book>?) {
bookList = it!!
notifyDataSetChanged()
}
private class BookViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
fun setData(a: String, b: String, p: Int) {
itemView.author.text = a
itemView.book.text = b
}
}
}
Based on this answer: How to update RecyclerView Adapter Data? I think that You have to notifyDataSetChanged from observer method not inside the adapter class.
viewModel.allBooks.observe(this, Observer { books ->
books?.let {
Log.d(TAG, "onCreate: changed")
bookListAdapter.setBooks(books)
bookListAdapter.notifyDataSetChanged()
}
})
fun setBooks(it: List<Book>) {
bookList = it
}
Also, when You use Room I think You can try to use DiffUtil. It will automatically refresh layout when it has to be refreshed and is much faster than calling notifyDataSetChanged every time Your data is changed.
I'm successfully passing data from MainActivity to my recyclerView via adapter, and my view with items is rendering correctly. However, I need to change one member of my item object on click (status), and i wrote a method for that (updateStatus), and it works great, it changes the value and save it to database.
But i cannot refresh my recyclerView, so it could render changed Status attribute. I need to go back on my phone, reenter, and then it renders it correctly. I have tried everything, from notifyDataSetChanged to restarting adapter, no luck. There is something missing and I can't find what.
Here is my MainActivity class
class MainActivity : AppCompatActivity() {
private var posiljkaDAO: PosiljkaDAO? = null
private var dostavnaKnjizicaDAO: DostavnaKnjizicaDAO? = null
private var allItems: ArrayList<DostavnaKnjizicaModel> = arrayListOf()
var adapter = RecycleViewAdapter(allItems)
private var eSifraPosiljke: EditText? = null
#RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_listview)
//get logo
supportActionBar!!.setDisplayShowHomeEnabled(true)
supportActionBar!!.setLogo(R.drawable.logo_bp)
supportActionBar!!.setDisplayUseLogoEnabled(true)
dostavnaKnjizicaDAO = DostavnaKnjizicaDAO(this)
dostavnaKnjizicaDAO?.closeDB()
getAllItems(this)
//connecting adapter and recyclerView
adapter = RecycleViewAdapter(allItems)
recycleView.adapter = adapter
recycleView.layoutManager = LinearLayoutManager(this)
recycleView.setHasFixedSize(true)
eSifraPosiljke = findViewById<EditText>(R.id.eSifraPosiljke)
posiljkaDAO = PosiljkaDAO(this)
}
//method that gets all items from database
private fun getAllItems(context: Context) {
var dostavenFromLOcal = dostavnaKnjizicaDAO?.getAllLocalDostavneKnjizice(context)
if (dostavenFromLOcal != null) {
allItems = dostavenFromLOcal
}
}
//method that changes status of an item
fun changeStatus(context: Context, IdDostavne: Int, statusDostavne: Int) {
dostavnaKnjizicaDAO = DostavnaKnjizicaDAO(context)
dostavnaKnjizicaDAO?.changeStatus(IdDostavne, statusDostavne)
getAllItems(context)
adapter.notifyDataSetChanged()
}
}
and my Adapter class
class RecycleViewAdapter(var dostavneKnjiziceBP: ArrayList<DostavnaKnjizicaModel>)
: RecyclerView.Adapter<RecycleViewAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view){
val nazivPrimaoca: TextView = view.txtNazivPrimaoca
val brojPosiljke: TextView = view.txtBrojPosiljke
val statusDostave: TextView = view.txtStatusDostave
val imgMore: ImageView = view.img_more
val context: Context = view.context
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val layoutView = LayoutInflater.from(parent.context).inflate(R.layout.urucenje_posiljke_layout, parent, false)
return ViewHolder(layoutView)
}
override fun getItemCount() = dostavneKnjiziceBP.size
#RequiresApi(Build.VERSION_CODES.KITKAT)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
//New variable to get all modeliPosiljakaBP and their position
var dosKnjizica = dostavneKnjiziceBP[position]
val mainActivity = MainActivity()
//Sending data to layout for display in specific field
if (dosKnjizica.naziv_primaoca != null) {
holder.brojPosiljke.text = "${dosKnjizica.id_dostavna_knjizica}, "
holder.nazivPrimaoca.text = "${dosKnjizica.naziv_primaoca}"
if (dosKnjizica.naziv_primaoca!!.length > 25) {
holder.nazivPrimaoca.text = "${dosKnjizica.naziv_primaoca!!.subSequence(0, 25)}..."
}
} else {
holder.brojPosiljke.text = "${dosKnjizica.id_dostavna_knjizica}"
holder.nazivPrimaoca.text = ""
}
holder.statusDostave.text = "${dosKnjizica.status_dostave_naziv}"
when (dosKnjizica.status_dostave) {
StatusDostaveEnum.Neurucena.value -> {
holder.statusDostave.setTextColor(Color.RED)
}
StatusDostaveEnum.Uruceno.value, StatusDostaveEnum.ZaRejon.value, StatusDostaveEnum.Nadoslano.value, StatusDostaveEnum.Izgubljeno.value -> {
holder.statusDostave.setTextColor(Color.GREEN)
}
StatusDostaveEnum.Obavjesteno.value, StatusDostaveEnum.ZaNarednuDostavu.value -> {
holder.statusDostave.setTextColor(Color.BLUE)
}
StatusDostaveEnum.Retour.value -> {
holder.statusDostave.setTextColor(Color.parseColor("#dda0dd"))
}
}
//Calling menu menu_pregled_drugih_vrsta_posiljke to display menu options on click on three dots
holder.imgMore.setOnClickListener {
val popupMenu = PopupMenu(holder.context, it, Gravity.START)
popupMenu.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.uruci -> {
//calling new activity from second item in dropdown menu
holder.imgMore.context.startActivity(
Intent(holder.imgMore.context, MainActivityInfo::class.java).putExtra(
"Id", dosKnjizica.id_dostavna_knjizica.toString()
)
)
true
}
//here i am calling my changeStatus method from MainActivity
R.id.obavjesti -> {
mainActivity.changeStatus(holder.context, dosKnjizica.id_dostavna_knjizica!!, StatusDostaveEnum.Uruceno.value)
Toast.makeText(holder.context, "obavjesti", Toast.LENGTH_SHORT).show()
true
}
R.id.vrati -> {
Toast.makeText(holder.context, "vrati", Toast.LENGTH_SHORT).show()
true
}
else -> false
}
}
popupMenu.inflate(R.menu.menu_urucenje_posiljke)
popupMenu.show()
}
}
}
Your adapter doesn't have the updated data. Initially, you fetch all data from the database and create an adapter with it: adapter = RecycleViewAdapter(allItems). Afterwards, you are updating the database, calling getAllItems(Context) but you don't pass the data to the adapter.
Add the line adapter.dostavneKnjiziceBP = allItems to the changeStatus method like this:
//method that changes status of an item
fun changeStatus(context: Context, IdDostavne: Int, statusDostavne: Int) {
dostavnaKnjizicaDAO = DostavnaKnjizicaDAO(context)
dostavnaKnjizicaDAO?.changeStatus(IdDostavne, statusDostavne)
getAllItems(context)
adapter.dostavneKnjiziceBP = allItems
adapter.notifyDataSetChanged()
}
Save dostavneKnjiziceBP as a private var inside the adapter and create functions for assigning and updating that ArrayList from within the adapter, using notifyDataSetChanged() everytime a change is done.
class RecycleViewAdapter internal constructor(
context: Context
) : RecyclerView.Adapter<RecycleViewAdapter.ViewHolder>() {
private var items = ArrayList<DostavnaKnjizicaModel>()
// ...
internal fun setItems(items: ArrayList<DostavnaKnjizicaModel>) {
this.items = items
notifyDataSetChanged()
}
override fun getItemCount() = this.items.size
}
Also, try using adapter.notifyItemChanged(updateIndex); if you know the index of the updated item.
I have 3 similars adapters and I want to combine them in 1. The only thing that is different is the ArrayList type. I have 2 room entities for room, FavoriteArticle, and HistoryArticle, but they have the same fields as WikiPage.
class Adapter<T> (#LayoutRes private val layoutRes: Int) : RecyclerView.Adapter<Holder>() {
val currentResult: ArrayList<T> = ArrayList()
override fun getItemCount() = currentResult.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val cardItem = LayoutInflater.from(parent.context).inflate(layoutRes, parent, false)
return Holder(cardItem)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val page = currentResult[position]
holder.updateWithPage(page)
}
fun add(wiki: ArrayList<T>?) { {
currentResult.clear()
if (wiki != null) {
currentResult.addAll(wiki)
}
}
}
Holder class:
class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val articleImageView: ImageView = itemView.findViewById(R.id.articleCardItemImage)
private val titleTextView: TextView = itemView.findViewById(R.id.articleCardItemTitle)
private lateinit var currentPage: WikiPage
init {
itemView.setOnClickListener {
itemView.context.startActivity(ArticleDetailActivity.createStartIntent(itemView.context, currentPage))
}
}
fun updateWithPage(page: WikiPage) {
currentPage = page
titleTextView.text = page.title
Picasso.get().load(page.thumbnail.source).into(articleImageView)
}
}
I can't figure out how to modify my updateWithPage function from onBindViewHolder using generics. How can I do this?
Some idea for your reference by using Interface:
interface Article {
getWikiPage(): WikiPage
}
class FavoriteArticle : Article {
getWikiPage() = wikiPage
}
class HistoryArticle: Article {
getWikiPage() = wikiPage
}
// Adapter
class Adapter<Article>
...
override fun onBindViewHolder(holder: Holder, position: Int) {
val page = currentResult[position].getWikiPage()
holder.updateWithPage(page)
}
...
You can make a generalized adapter that can accept any viewholder class. This will require pushing the viewholder creation logic inside the viewholder class itself. Using some kotlin extension functions can even be a lot cleaner for this use case.
Check out this link: https://thecommonwise.com/blogs/60f6ea9bea3d10001503eac3
I want to create an android app with Kotlin. In this app, i use swagger also to get all the web service in a file.
I want to create an interface, the description is as follows:
A RecyclerView horizontal that contains all the list of categories
comes from a web service apiMobileProductCategoriesGetAllPost.
after that, when i click on a which category, a RecyclerView(Grid)
appear that contains all the product by category id.
I want to know how can i get the category id when i click on item,and how to use it in the activity
The following the RecyclerView category adapter:
class CategoryAdapter(private val categories: Array<ProductCategoryData>) :
RecyclerView.Adapter<CategoryAdapter.ViewHolder>(), View.OnClickListener {
private var onItemClickListener: OnItemClickListener? = null
override fun onClick(v: View?) {
if (v != null) {
onItemClickListener?.onItemClick(v, ProductCategoryData())
}
}
fun setOnItemClickListener(onItemClickListener: OnItemClickListener) {
this.onItemClickListener = onItemClickListener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.category_item, parent, false)
view.setOnClickListener(this)
return ViewHolder(view)
}
override fun getItemCount() = categories.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val itemCategory: ProductCategoryData = categories[position]
holder.categoryId.text = itemCategory.id.toString()
println(holder.categoryId.text)
println(itemCategory.name?.get("En").toString())
holder.categoryName.text = itemCategory.name?.get("En").toString()
println(itemCategory.id)
if (itemCategory.logo != null) {
Picasso.get()
.load("..../T/${itemCategory.logo}")
.into(holder.categoryImage, object : com.squareup.picasso.Callback {
override fun onError(e: Exception?) {
holder.categoryImage.setImageResource(R.drawable.homecraftdefault)
}
override fun onSuccess() {
Picasso.get().load("....T/${itemCategory.logo}")
.into(holder.categoryImage)
}
})
holder.itemView.setOnClickListener {
onItemClickListener?.onItemClick(holder.itemView,itemCategory)
}
}
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
val categoryName: TextView = itemView.categoryName
val categoryImage: ImageView = itemView.categoryImage
val categoryId: TextView = itemView.categoryId
override fun onClick(v: View?) {
if (v != null) {
onItemClickListener?.onItemClick(v, ProductCategoryData())
}
}
}
interface OnItemClickListener {
fun onItemClick(view : View, viewModel:ProductCategoryData)
}
}
The following code is relative to the activity:
class CategoryByProduct : AppCompatActivity(), CategoryAdapter.OnItemClickListener {
override fun onItemClick(view: View, viewModel: ProductCategoryData) {
var params = "CategoryProductID";"5cc057458c4d9823743736d2"
println(viewModel.id)
val products = mobileApi!!.apiMobileProductsGetAllPost(params, 0, 50, "", "")
recyclerViewProductByCategory.apply {
recyclerViewProductByCategory.layoutManager = GridLayoutManager(this#CategoryByProduct, 2)
recyclerViewProductByCategory.adapter = ProductAdapter(products)
} }
var mobileApi: MobileApi? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.list_product_by_category)
mobileApi = MobileApi()
val params = HashMap<String, String>()
GlobalScope.launch(Dispatchers.IO) {
val categories = mobileApi!!.apiMobileProductCategoriesGetAllPost(params, 0, 50, "", "")
withContext(Dispatchers.Main) {
recyclerViewCategories.apply {
recyclerViewCategories.layoutManager =
LinearLayoutManager(this#CategoryByProduct, OrientationHelper.HORIZONTAL, false)
recyclerViewCategories.adapter = CategoryAdapter(categories)
}
}
}
}
}
First of all , never put your onclick in onBindViewHolder That's not a good practice, after that i think you need to get the ID of the category i will give you simple example in all of the Adapter Class
class NewsAdapter (val context: Context, private val arrayList: ArrayList <NewsModel>):
RecyclerView.Adapter <NewsAdapter.Holder> () {
companion object {
// val TAG: String = OperationAdapter::class.java.simpleName
}
override fun onCreateViewHolder (parent: ViewGroup, viewType: Int): Holder {
return Holder (LayoutInflater.from (parent.context ).inflate (R.layout.newslist , parent, false))
}
override fun getItemCount (): Int = arrayList. size
override fun onBindViewHolder (holder: Holder, position: Int) {
val mynews = arrayList[position]
holder.setData(mynews , position)
}
inner class Holder (itemView: View): RecyclerView.ViewHolder (itemView) {
private var currentnews: NewsModel? = null
private var currentPosition: Int = 0
init {
//The click listener
itemView.newscardview.setOnClickListener {
//do it here
Toast.makeText(this,currentnews!!.id,Toast.LENGTH_SHORT).show()
}
//the end of the init
}
//getting data from model and bind it into View
fun setData(news: NewsModel?, position: Int) {
news?.let {
itemView.newsid.text = news.id
itemView.newstitle.text = news.title
itemView.body.text = news.body
itemView.txtdate.text = news.ndate
}
this.currentnews = news
this.currentPosition = position
}
}
}
In this example you will get the news ID when you click newscardview, i hope to understand it
In your Activity
put this code in onCreate
//set up the recycleview
mRecyclerView.setHasFixedSize (true)
mRecyclerView. layoutManager = LinearLayoutManager(this)
mRecyclerView is my RecycleView
also call your Adapter class in anywhere you want
//adapter
val adapter = NewsAdapter (this,arrayList)
adapter.notifyDataSetChanged()
mRecyclerView.adapter = adapter
you get the position of the category inside a viewholder by calling adapterPosition and with this you can get the category from your list you provide to your adapter in the constructor (categories[adapterPosition])
In your case it is very simple.Try these:-
holder.tv_broadcast_title.text=broadList[position].name
where broadlist is my array list created in the adapter itself.In this list the json data is getting stored from api.
internal var broadList = ArrayList<Model>()
and .name is the name of key to fetch name from json data.
holder.categoryName.text = itemCategory.name?.get("En").toString()
in your case do something like this:-
itemCategory[position].name
To get data from adapter to activity, you can make an interface in the adapter or globally and from the activity you can pass that interface in adapter's constructor and use that to get data. I am giving you an example.
interface ProductCategoryListner {
fun getProductCategory(viewModel:ProductCategoryData)
}
Not in adapter's constructor add this interface.
class CategoryAdapter(private val categories: Array<ProductCategoryData>,private val productCategoryListner: ProductCategoryListner):
RecyclerView.Adapter<CategoryAdapter.ViewHolder>(), View.OnClickListener {
Now you can use this to pass data in the activity when you click on view.
productCategoryListner.getProductCategory(categories[adapterPosition])