How to get data recycleview to parse on other updateactivity? - android-recyclerview

I have code in ListBukpotAdapter, how can I get data listener.OnClick(currentItem) to parse on other UpdateActivity
Error:
kotlin.UnitializedPropertyAccessExeption: lateinit property listener has not been initialized
class ListBukpotAdapter : RecyclerView.Adapter<ListBukpotAdapter.MyViewHolder>() {
private var bukpotList = emptyList<QrResultBukpot>()
private lateinit var listener: OnAdapterListener
interface OnAdapterListener {
fun OnClick(bukpotDataParsing: QrResultBukpot)
}
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.custom_row_bukpot, parent, false))
}
override fun getItemCount(): Int {
return bukpotList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = bukpotList[position]
holder.itemView.txtNomorBukpot.text = currentItem.nomorBukpot
holder.itemView.txtNpwpPemotong.text = currentItem.npwpPemotong
holder.itemView.txtMasaPajak.text = currentItem.masaPajak + " / " + currentItem.tahunPajak
holder.itemView.txtMixCode.text = currentItem.mixCode
holder.itemView.rowLayoutBukpot.setOnClickListener {
listener.OnClick(currentItem)
val context = holder.itemView.context
val intent = Intent(context, UpdateBukpotActivity::class.java)
context.startActivity(intent)
}
}
fun setDataBukpot(bukpot: List<QrResultBukpot>){
this.bukpotList = bukpot
notifyDataSetChanged()
}
}

You should initilaze your listener. Your listener variable is lateinit so before you use this, you need to initialize. You can give listener as a constructor parameter from your activity or fragment and can listen interface from your activity or fragment which contains recyclerview.

Related

E/RecyclerView: No adapter attached; skipping layout while getting the data from Google Spreadsheet

I am trying to get the data from the Google Spreadsheet and display it in a recyclerView in Kotlin. But I am getting the error as in the title.
I know there are many questions about the error 'E/RecyclerView: No adapter attached'. I spent hours going through all the posts and made changes to my code. But I couldn't fix the issue as I am not an expert coder.
Following is SalesData.kt
class SalesData : AppCompatActivity() {
private lateinit var binding: ActivitySalesDataBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySalesDataBinding.inflate(layoutInflater)
setContentView(binding.root)
val salesList = arrayListOf<SalesDataModel>()
binding.rvSalesData.layoutManager = LinearLayoutManager(applicationContext)
binding.rvSalesData.setHasFixedSize(true)
val adapter = SalesDataRecyclerAdapter(applicationContext,salesList)
binding.rvSalesData.adapter = adapter
val queue = Volley.newRequestQueue(this)
val url = "https://script.google.com/macros/s/fssfsdffdfhfhPPEWVM2FeIH3gZY5kAnb6JVeWpg2Xedfgt443534tdfg43t/exec"
val jsonObjectRequest = object: JsonObjectRequest(Request.Method.GET,url,null,Response.Listener {
val data = it.getJSONArray("items")
for(i in 0 until data.length()){
val salesJasonObject = data.getJSONObject(i)
val salesObject = SalesDataModel(
salesJasonObject.getString("Date"),
salesJasonObject.getString("Branch"),
salesJasonObject.getDouble("NetSale"),
salesJasonObject.getDouble("Profit"),
)
salesList.add(salesObject)
adapter.notifyDataSetChanged()
}
},Response.ErrorListener { }
){
override fun getHeaders(): MutableMap<String, String> {
return super.getHeaders()
}
}
}
}
and this is the adapter class SalesDataRecyclerAdapter.kt
class SalesDataRecyclerAdapter(val context: Context, private val saleDataList:ArrayList<SalesDataModel>)
:RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return MyViewHolder(
SalesDataLayoutBinding.inflate(
LayoutInflater.from(
parent.context
), parent, false
)
)
}
override fun getItemCount(): Int {
return saleDataList.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val model = saleDataList[position]
if (holder is MyViewHolder){
holder.binding.tvSales.text = model.salesAmount.toString()
holder.binding.tvBranch.text = model.branch
holder.binding.tvDate.text = model.date
holder.binding.tvProfit.text = model.profit.toString()
}
}
private class MyViewHolder(val binding: SalesDataLayoutBinding) : RecyclerView.ViewHolder(binding.root)
}

How to delete a record in room database with recyclerview MVVM

I need to delete an item recyclerview adapter which should be notified in room database, please help me in finding a solution and thanks in advance
class ListAdapter : RecyclerView.Adapter<ListAdapter.MyViewHolder>() {
private lateinit var mitemsViewModel: ItemsViewModel
private var itemsList = emptyList<Item>()
private lateinit var item: Item
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_row_layout, parent, false)
)
}
override fun getItemCount(): Int {
return itemsList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
item = itemsList.get(position)
//always remember this technique to save the values in val type
val currentItem = itemsList[position]
holder.itemView.itemNameTV.text = currentItem.itemName.toString()
holder.itemView.itemCodeTV.text = currentItem.itemCode.toString()
holder.itemView.itemCategoryTV.text = currentItem.itemCategory.toString()
holder.itemView.itemDescriptionTV.text = currentItem.itemDescription.toString()
holder.itemView.itemSellingPriceTV.text = currentItem.itemSellingPrice.toString()
holder.itemView.itemStockTV.text = currentItem.itemStock.toString()
holder.itemView.deleteItem.setOnClickListener {
val itName = holder.itemView.itemNameTV.text.toString()
val itCode = holder.itemView.itemCodeTV.text.toString()
val itCategory = holder.itemView.itemCategoryTV.text.toString()
val itDescription = holder.itemView.itemDescriptionTV.text.toString()
val itSellingPrice = holder.itemView.itemSellingPriceTV.text.toString()
val itStock = holder.itemView.itemStockTV.text.toString()
val itime = Item(0, itName, itCode, itCategory, itSellingPrice, itStock, itDescription)
mitemsViewModel.deleteItem(itime)
//dao.deleteItem(itemsList.get(position))
}
}
fun setData(item: List<Item>) {
this.itemsList = item
notifyDataSetChanged()
}}
Help me how to initialize the ViewModel in recyclerview adapter.
The error code after running my app
kotlin.UninitializedPropertyAccessException: lateinit property mitemsViewModel has not been initialized
at com.manju.mobilebilling.ui.items.ListAdapter.onBindViewHolder$lambda-0(ListAdapter.kt:65)
at com.manju.mobilebilling.ui.items.ListAdapter.$r8$lambda$pJauI4KaymNCF6j043M3H3t3CwQ(ListAdapter.kt)
at com.manju.mobilebilling.ui.items.ListAdapter$$ExternalSyntheticLambda0.onClick(D8$$SyntheticClass)
at android.view.View.performClick(View.java:5651)
at android.view.View$PerformClick.run(View.java:22445)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6138)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:893)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:783)
You should initialize the ItemsViewModel in the parent Activity or Fragment:
private val viewModel by viewModels<ItemsViewModel>()
Then, instead of passing it directly to the ListAdapter declare a custom click listener and use that as parameter:
// Add a parameter in the adapter
class ListAdapter(
private val clickListener: ListClickListener
) : RecyclerView.Adapter<ListAdapter.MyViewHolder>() {
private var itemsList = emptyList<Item>()
private lateinit var item: Item
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_row_layout, parent, false)
)
}
override fun getItemCount(): Int {
return itemsList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
item = itemsList.get(position)
//always remember this technique to save the values in val type
val currentItem = itemsList[position]
holder.itemView.itemNameTV.text = currentItem.itemName.toString()
holder.itemView.itemCodeTV.text = currentItem.itemCode.toString()
holder.itemView.itemCategoryTV.text = currentItem.itemCategory.toString()
holder.itemView.itemDescriptionTV.text = currentItem.itemDescription.toString()
holder.itemView.itemSellingPriceTV.text = currentItem.itemSellingPrice.toString()
holder.itemView.itemStockTV.text = currentItem.itemStock.toString()
holder.itemView.deleteItem.setOnClickListener {
val itName = holder.itemView.itemNameTV.text.toString()
val itCode = holder.itemView.itemCodeTV.text.toString()
val itCategory = holder.itemView.itemCategoryTV.text.toString()
val itDescription = holder.itemView.itemDescriptionTV.text.toString()
val itSellingPrice = holder.itemView.itemSellingPriceTV.text.toString()
val itStock = holder.itemView.itemStockTV.text.toString()
val itime = Item(0, itName, itCode, itCategory, itSellingPrice, itStock, itDescription)
// Call the click listener
clickListener.onClick(iitem)
}
}
fun setData(item: List<Item>) {
this.itemsList = item
notifyDataSetChanged()
}
}
// Click listener class
class ListClickListener(val clickListener: (item: Item) -> Unit) {
fun onClick(item: Item) = clickListener(item)
}
Finally, declare your ListAdapter in the parent Activity or Fragment with:
val adapter = ListAdapter(ListClickListener { item ->
viewModel.deleteItem(item)
})
Initialize your viewmodel in your activity than pass it via adapter constructor

Show item info on selected item in RecyclerView using Kotlin

I am using kotlin language with android studio. I want to get the properties of the element I clicked in the RecyclerView.
Ben bu kod ile saderc id alabiliyorum
Ex: date
ListAdapter.kt
class ListAdapter(
private val context: Context
) : RecyclerView.Adapter<ListAdapter.ListViewHolder>() {
private var dataList = mutableListOf<Any>()
private lateinit var mListener: onItemClickListener
interface onItemClickListener {
fun onItemClick(position: Int)
}
fun setOnItemClickListener(listener: onItemClickListener) {
mListener = listener
}
fun setListData(data: MutableList<Any>) {
dataList = data
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.item_row, parent, false)
return ListViewHolder(view)
}
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
val question: Questionio = dataList[position] as Questionio
holder.bindView(question)
}
override fun getItemCount(): Int {
return if (dataList.size > 0) {
dataList.size
} else {
return 0
}
}
inner class ListViewHolder(itemView: View, listener: onItemClickListener) :
RecyclerView.ViewHolder(itemView) {
fun bindView(questionio: Questionio) {
itemView.findViewById<TextView>(R.id.txt_policlinic).text = questionio.policlinic
itemView.findViewById<TextView>(R.id.txt_title).text = questionio.title
itemView.findViewById<TextView>(R.id.txt_description).text = questionio.description
itemView.findViewById<TextView>(R.id.txt_date).text = questionio.date
itemView.findViewById<TextView>(R.id.txt_time).text = questionio.time
}
init {
itemView.setOnClickListener {
listener.onItemClick(adapterPosition)
}
}
}
}
My code in onCreateView inside list fragment.Edit
ListFragment
recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerView.adapter = adapter
observeData()
adapter.setOnItemClickListener(object : ListAdapter.onItemClickListener {
override fun onItemClick(position: Int) {
showShortToast(position.toString())
}
})
this function is also my observationData(),
I made new edits
private fun observeData() {
binding.shimmerViewContainer.startShimmer()
listViewModel.fetchQuestinData("questions",
requireContext())
.observe(viewLifecycleOwner, {
binding.shimmerViewContainer.startShimmer()
binding.shimmerViewContainer.hideShimmer()
binding.shimmerViewContainer.hide()
adapter.setListData(it)
adapter.notifyDataSetChanged()
})
}
You can pass highOrderFuction into the adapter then setonclickListener for any view you want. Like this:
class ListAdapter(
private val context: Context,
private val onItemClick:(questionio: Questionio)->Unit
) : RecyclerView.Adapter<ListAdapter.ListViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.item_row, parent, false)
return ListViewHolder(view,onItemClick)
}
...
inner class ListViewHolder(itemView: View,private val onItemClick:(questionio: Questionio)->Unit) : RecyclerView.ViewHolder(itemView) {
fun bindView(questionio: Questionio) {
//set on any view you want
itemView.findViewById<TextView>(R.id.root_view_id).
setOnClickListener{onItemClick(questionio)}
itemView.findViewById<TextView>(R.id.txt_policlinic).text =
questionio.policlinic
itemView.findViewById<TextView>(R.id.txt_title).text = questionio.title
itemView.findViewById<TextView>(R.id.txt_description).text =
questionio.description
itemView.findViewById<TextView>(R.id.txt_date).text = questionio.date
itemView.findViewById<TextView>(R.id.txt_time).text = questionio.time
}
}
}

Recyclerview does not display on the screen in kotlin

So I tried to create multi views recyclerview in kotlin, but sadly it did not work.The recyclerview does not display on the screen. It worth to mention that I tried to set the orientation as vertical in my layout files, also added all the dependencies and things needed. Can anyone please help me with that?
My MainActivity.class
#AndroidEntryPoint
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
lateinit var adapter: NumbersAdapter
lateinit var recyclerView: RecyclerView
var list: List<Nums> = listOf(Nums(1,false))
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
updateAll()
}
fun updateAll(){
binding.recyclerview.apply {
val layoutManager = LinearLayoutManager(this#MainActivity)
adapter = NumbersAdapter(list)
adapter = adapter
}}}
My Adapter
class NumbersAdapter(
var list: List<Nums>,
): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class RedViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val name = itemView.findViewById<TextView>(R.id.red_number)
fun bindRed(number: Nums) {
name.text = number.nums.toString()
}
}
class OrangeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val name = itemView.findViewById<TextView>(R.id.orange_number)
fun bindOrange(number: Nums) {
name.text = number.nums.toString()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == 0) {
val redvView =
LayoutInflater.from(parent.context).inflate(R.layout.red_item, parent, false)
return RedViewHolder(redvView)
}
else {
val orangeView =
LayoutInflater.from(parent.context).inflate(R.layout.orange_item, parent, false)
return OrangeViewHolder(orangeView)
}
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if(getItemViewType(position)==0){
(holder as RedViewHolder).bindRed(list[position])
}
else{
(holder as OrangeViewHolder).bindOrange(list[position])
}
}
override fun getItemViewType(position: Int): Int {
checkItem()
if(list[position].flag)
return 0
return 1
}
fun checkItem(){
for (i in list.indices) {
for (k in i + 1 until list.size) {
if (list[i].nums + list[k].nums == 0) {
list[i].flag = true
list[k].flag = true
}}}}}
in MainActivity.class change code in updateAll() function
fun updateAll(){
binding.recyclerView.apply {
adapter = NumbersAdapter(list)
layoutManager = LinearLayoutManager(this#MainActivity)
}
}

Why does private lateinit var mCustomAdapter CustomAdapter cause Property getter or setter expected in Kotlin?

The code mRecyclerView.adapter= CustomAdapter(allList) works well, I hope to define a private var mCustomAdapter, and assign value late.
But the code private lateinit var mCustomAdapter CustomAdapter cause error, how can I fixed it? Thanks!
Code A
class UIMain : AppCompatActivity() {
private lateinit var mCustomAdapter CustomAdapter //Error
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_main)
...
mRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
mRecyclerView.adapter= CustomAdapter(allList) //OK
}
Code B
class CustomAdapter (val backupItemList: List<MSetting>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
private var mSelectedItem = -1
//this method is returning the view for each item in the list
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.item_recyclerview, parent, false)
return ViewHolder(v)
}
fun getSelectedItem():Int{
return mSelectedItem
}
//this method is binding the data on the list
override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
holder.bindItems(backupItemList[position])
holder.itemView.radioButton.setChecked(position == mSelectedItem);
}
//this method is giving the size of the list
override fun getItemCount(): Int {
return backupItemList.size
}
//the class is hodling the list view
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(aMSetting: MSetting) {
//itemView.radioButton.isChecked=false
itemView.radioButton.tag=aMSetting._id
itemView.textViewUsername.text=aMSetting.createdDate.toString()
itemView.textViewAddress.text=aMSetting.description
itemView.radioButton.setOnClickListener {
mSelectedItem=getAdapterPosition()
notifyDataSetChanged();
}
}
}
}
You are missing : at the end of mCustomAdapter variable
Try this:
private lateinit var mCustomAdapter: CustomAdapter
See more: https://kotlinlang.org/docs/reference/basic-syntax.html#defining-variables