RecyclerView only showing last item in JSON array - android

Based on the logs I added in, the request is receiving all the data correctly, and the issues lies somewhere in displaying the list in the recycler list. It just prints out the last item in the your server pets array and prints its according to the length of the database array. My leaderboard seems to only been showing the last entry into the database and repeating it for the pets array length. I would like to show the entire database items in each slot. Also, I am not sure why petPhoto is not being passed through like everything other thing.
***************************************ListAcitivty.kt:****************************************
package com.example.specialpets
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
import org.json.JSONArray
import org.json.JSONObject
class ListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_list)
var findArray: JSONArray
val url = "https://jwuclasses.com/ugly/leaderboard"
val jsonData=JSONObject();
val queue = Volley.newRequestQueue(this);
val request = JsonObjectRequest(Request.Method.POST, url, jsonData,
{ response ->
if (response.getInt("success") == 1) {
Log.e("app", "We have something good going on here");
findArray = response.getJSONArray("pets")
for (i in 0 until findArray.length()) {
val pet = findArray.getJSONObject(i)
val petListID = pet.getInt("id")
val petName = pet.getString("name")
val petBirthdate = pet.getString("birthdate")
val petRating = pet.getInt("rating")
val petVotes = pet.getDouble("votes")
val petPhoto = pet.getString("url")
jsonData.put("token",TokenBox.token)
//pay no attention to the man behind the curtain
//val petName = response.getString("name")
// val petListID = response.getInt("id")
//val petRating = response.getInt("rating")
// val petBirthdate = response.getString("birthdate")
// val petVotes = response.getInt("votes")
val data = ArrayList<petViewModel>()
//data.sortDescending(); Why won't this work??? Maybe because it has to be in the declaration of the array
for(i in 0 until findArray.length()) {
data.add(
petViewModel(
petListID,
petName,
petBirthdate,
petRating,
petVotes,
petPhoto
)
)
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
val adapter = petAdapter(data)
recyclerView.adapter = adapter
}
}
} else {
Log.e("app", "something isn't right here")
}
},{
error ->
Log.e("app", "Request did not go through and no JSON data was sent")
})
request.setShouldCache(false);
queue.add(request);
//val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
//val data = ArrayList<petViewModel>()
// for(i in 1..20){}
//****These are all my attempts at passing the data through a jsonObject request....
// data.add(petViewModel("petListID", "petName", "petBirthdate", "petRating", "petVotes",)
//take it from JSON, store it in a local array and store it
//data.add(petViewModel("Item" + i, i))
// data.add(petViewModel((response.getString("id"), response.getString("name"), response.getString("birthdate"), response.getString("rating"), response.getString("votes"))
//data.add(petViewModel(2, 2, 3, 10))
// data.add(petViewModel(response.getInt,"id", response.getString,"birthdate", response.getString""
//data.add(petViewModel(reponse.getString,"name", response.getString,"birthdate", response.getString,"rating")
//data.add(petViewModel("id", "", "", "", ""))
//data.add(petViewModel((response.getString"")))
//data.add(petViewModel("id", "name", "rating", "birthdate", "votes"))
//}
}
}
******************************************PetViewModel:****************************************
package com.example.specialpets
//class designed to hold data
data class petViewModel(val id: Int, val name: String, val birthdate: String, val rating: Int, val votes: Double, val url: String){
//id name birthdate rating votes url(picasso image)
}
******************************************PetAdapterModel:****************************************
package com.example.specialpets
import android.content.Intent
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
import com.squareup.picasso.Picasso
import org.json.JSONArray
import org.json.JSONObject
//an array of petviewmodel instances
class petAdapter(val dataset: ArrayList<petViewModel>): RecyclerView.Adapter<petAdapter.ViewHolder>() {
//creates a new item or a new card for a pet
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.petcard, parent, false)
return ViewHolder(view)
}
//puts the position. specific information
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val petViewModel = dataset[position]
holder.petListID.text = petViewModel.id.toString()
holder.petName.text = petViewModel.name
holder.petBirthdate.text = petViewModel.birthdate
holder.petRating.text = petViewModel.rating.toString()
holder.petVotes.text = petViewModel.votes.toString()
//picassoimg
holder.petListID.setOnClickListener{
//grab id from data object which is inside the petviewmodel
val zoomies = Intent(holder.petListID.context,ZoomerActivity::class.java)
//store with the one click one
zoomies.putExtra("ID", petViewModel.id.toString())
zoomies.putExtra("name", petViewModel.name)
zoomies.putExtra("birthdate", petViewModel.birthdate)
zoomies.putExtra("rating", petViewModel.rating.toString())
zoomies.putExtra("votes", petViewModel.votes.toString())
zoomies.putExtra("url", petViewModel.url)
//start the activity
holder.petListID.context.startActivity(zoomies)
}
}
//tells me how many items are in the list
override fun getItemCount(): Int {
return dataset.size
}
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView){
val petListID: TextView = ItemView.findViewById(R.id.petListID)
val petName: TextView = ItemView.findViewById(R.id.petName)
val petBirthdate: TextView = ItemView.findViewById(R.id.petBirthdate)
val petRating: TextView = ItemView.findViewById(R.id.petRating)
val petVotes: TextView = ItemView.findViewById(R.id.petVotes)
}
}
I would like it to have every item instead of just the last item in the JSON array.I have tried changing the for loop to a forEach loop with no changes. I have tried altering the data class: dataset with no changes as well.
this is what the app recyler view looks like

You can try following this:
class YourAdapterName(
private val context: Context,
private val dataset: ArrayList<petViewModel>
) :
RecyclerView.Adapter<HistoryAdapter.ViewHolder>() {
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val yourview: TextView = view.findViewById(R.id.historyInput)
// and your other views
init {
item.setOnClickListener {
// here is what you want do when an item is clicked
}
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.yourRecyclerViewLayoutShouldBeHere, viewGroup, false)
return ViewHolder(v)
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
val petViewModel = dataset[position]
viewHolder.yourview.text = petViewModel.name
// and your other views here
}
// Return the size of your ids
override fun getItemCount() = dataset.size
}
It should be all you need.

Related

How to display suggestions for AutocompleteTextView and onItemClick display that item in a recyclerview with more information about the item

I'm creating a POS system where I'm trying to display items name in a suggestion list under the autocompletetextview and i was able to create it, But when it came to the onItemClick i hit a wall and i couldn' t display the item in a recyclerview. i did my research but couldn't find how to get these info from the database and display them in the recyclerview and i had a hard time trying to figure out if it's a problem from the Adapter or i wrote my code wrong. so can anyone help me ?
i'm trying to display the selected items from the suggestions list in the recyclerview with more info about about the item like unit price.
this is what i tried
this is the Activity where the autocompletetextview is and the listview
package com.mycodlabs.pos.ui
import android.content.Context
import android.os.Bundle
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.mycodlabs.pos.R
import com.mycodlabs.pos.db.AndroidDatabase
import com.mycodlabs.pos.db.DatabaseTables
import com.mycodlabs.pos.db.inventory.InventoryDao
import com.mycodlabs.pos.db.inventory.InventoryDbo
import com.mycodlabs.pos.domain.inventory.ProductModel
import com.mycodlabs.pos.ui.sale.adapter.MyAdapter
import kotlinx.android.synthetic.main.activity_pos.*
import kotlinx.android.synthetic.main.dialog_saleedit.*
import kotlinx.android.synthetic.main.pos_bottom_sheet.*
class PosActivity : AppCompatActivity() {
private lateinit var bottomSheetBehavior: BottomSheetBehavior<LinearLayout>
private lateinit var autoCompleteTextView: AutoCompleteTextView
private lateinit var productNames: ArrayList<String>
private lateinit var recyclerView: RecyclerView
private lateinit var adapter: MyAdapter
private var selectedItems = ArrayList<ProductModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_pos)
// for Back button
back.setOnClickListener {
finish()
}
//for the bottomsheet
bottomSheetBehavior = BottomSheetBehavior.from<LinearLayout>(std_btm_sht)
bottomSheetBehavior.setBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, state: Int) {
print(state)
when (state) {
BottomSheetBehavior.STATE_HIDDEN -> {
}
BottomSheetBehavior.STATE_EXPANDED -> {
}
BottomSheetBehavior.STATE_COLLAPSED -> {
}
BottomSheetBehavior.STATE_DRAGGING -> {
}
BottomSheetBehavior.STATE_SETTLING -> {
}
BottomSheetBehavior.STATE_HALF_EXPANDED -> {
}
}
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
}
})
// Auto Complete Textview filtering from Product table colm "productName"
val autoCompleteTextView = findViewById<AutoCompleteTextView>(R.id.searchBoxPos)
val productNames = ArrayList<String>()
var dbHelper = AndroidDatabase(this)
val db = dbHelper.readableDatabase
val cursor = db.rawQuery(
"SELECT DISTINCT ${InventoryDbo.colm_productName} FROM ${DatabaseTables.TABLE_PRODUCT} WHERE ${InventoryDbo.colm_productName} like '%%'"
,null
)
if (cursor.moveToFirst()) {
do {
productNames.add(cursor.getString(cursor.getColumnIndex("${InventoryDbo.colm_productName}")))
} while (cursor.moveToNext())
}
cursor.close()
db.close()
val adapterr = ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, productNames)
autoCompleteTextView.setAdapter(adapterr)
//// Auto Complete suggestion item display in recyclerview on select
// Create the RecyclerView
val recyclerView = findViewById<RecyclerView>(R.id.sale_List_Pos)
//// Create a layout manager for the RecyclerView
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
//// Create an empty list to store the selected items
var selectedItems = ArrayList<ProductModel>()
//// Create an adapter for the RecyclerView
val adapter = MyAdapter(selectedItems)
recyclerView.adapter = adapter
// Set an item click listener for the AutoCompleteTextView
searchBoxPos.setOnItemClickListener { _, _, position, _ ->
// Get the selected product name and product from the list
val selectedProductName = productNames[position]
val selectedProduct = InventoryDbo.getInstance(applicationContext).getProductByName(selectedProductName)
//InventoryDbo.getProductByName(selectedProductName)
// Add the selected product to the selected items list
selectedItems.add(selectedProduct as ProductModel)
// Notify the adapter that the data has changed
adapter.notifyDataSetChanged()
// Clear the focus and text from the AutoCompleteTextView
searchBoxPos.clearFocus()
searchBoxPos.setText("")
}
}
}
this is the Adapter
package com.mycodlabs.pos.ui.sale.adapter
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.mycodlabs.pos.R
import com.mycodlabs.pos.domain.inventory.ProductModel
import com.mycodlabs.pos.domain.inventory.ProductModel1
import kotlinx.android.synthetic.main.pos_item_card.view.*
class MyAdapter(var selectedItems: List<ProductModel>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val pname = itemView.pos_name
val pprice = itemView.pos_price
// val pqty = itemView.pos_qty
// val pimage = itemView.pos_image
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.pos_item_card, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val pos: ProductModel = selectedItems[position]
holder.pname.text = pos.name
holder.pprice.text = pos.unitPrice.toString()
// holder.pimage.= pos.image
// holder.pqty.text = pos.stockQty.toString()
}
override fun getItemCount() = selectedItems.size
}

How can pass data from recyclerview to New Activity

hi i want parse my data in to new activity .
I did this but it doesn't work properly and it doesn't transfer data
You can see my code below
my adapter
ItemViewAdapter.kt
package com.example.app.adapter
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.app.R
import com.example.app.models.products.Results
import com.example.app.ui.home.DescriptionActivity
import java.security.AccessController.getContext
class ItemViewAdapter(private val context: Context) :
RecyclerView.Adapter<ItemViewAdapter.MyViewHolder>() {
private var itemList: MutableList<Results> = mutableListOf()
private var page: Int = 0
fun setListItem(item: List<Results>) {
itemList.addAll(item)
notifyItemRangeInserted(page * 10, (page.plus(1) * 10) - 1)
}
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val title = view.findViewById<TextView>(R.id.tvTitle)
private val code = view.findViewById<TextView>(R.id.tvNumber)
private val quantity = view.findViewById<TextView>(R.id.tvQuantity)
private val price = view.findViewById<TextView>(R.id.tvPrice)
private val available = view.findViewById<TextView>(R.id.tvAvailable)
private val category = view.findViewById<TextView>(R.id.tvCategory)
fun bind(item: Results) {
title.text = item.name
code.text = item.code.toString()
quantity.text = item.quantities[0].quantity.toString()
price.text = item.prices[0].price.toString()
available.text = item.active.toString()
category.text = item.category?.name
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
return MyViewHolder(v)
}
override fun getItemCount(): Int {
return itemList.size
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val data = itemList[position]
holder.bind(data)
holder.itemView.setOnClickListener {
val intent = Intent(context, DescriptionActivity::class.java)
intent.putExtra("title", getItemId(position))
intent.putExtra("code", getItemId(position))
intent.putExtra("quantity", getItemId(position))
intent.putExtra("price", getItemId(position))
intent.putExtra("category", getItemId(position))
intent.putExtra("info", getItemId(position))
context.startActivity(intent)
}
}
}
and my description activity
Description.kt
package com.example.app.ui.home
import android.graphics.Color
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.view.WindowInsetsController
import android.view.WindowManager
import com.example.app.R
import com.example.app.databinding.ActivityDescriptionBinding
#Suppress("DEPRECATION")
class DescriptionActivity : AppCompatActivity() {
private lateinit var binding: ActivityDescriptionBinding
override fun onCreate(savedInstanceState: Bundle?) {
window.apply {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
statusBarColor = Color.TRANSPARENT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
this#DescriptionActivity.window.decorView.windowInsetsController
?.setSystemBarsAppearance(
0,
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
)
}
}
}
super.onCreate(savedInstanceState)
binding = ActivityDescriptionBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
getItemIntent()
}
private fun getItemIntent(){
val title = intent.getStringExtra("title")
val code = intent.getStringExtra("code")
val category = intent.getStringExtra("category")
val info = intent.getStringExtra("info")
val price = intent.getStringExtra("price")
val quantity = intent.getStringExtra("quantity")
setData(title,code,category,info,price,quantity)
}
private fun setData(title: String?, code: String?, category: String?, info: String?, price: String?, quantity: String?) {
binding.tvTitle.setText(title)
binding.tvCode.setText(code)
binding.tvCategory.setText(category)
binding.tvDescription.setText(info)
binding.tvPrice.setText(price)
binding.tvQuantity.setText(quantity)
}
}
But the data is not transferred.
If anyone can help me improve the code or offer me a sample code done with api so I can see.
When you set the data, you call getItemId(position) for every single line. This returns a long, not a string (and you put the same long for each attribute, which makes no sense)
intent.putExtra("title", getItemId(position))
intent.putExtra("code", getItemId(position))
but when you retrieve it, you look for a string
val title = intent.getStringExtra("title")
val code = intent.getStringExtra("code")
If you want to get a string, you need to put a string, probably like this (get the item for that row, then put its string attributes):
val data = itemList[position]
//...
intent.putExtra("title", data.name)
intent.putExtra("code", data.code.toString())
or if you want to get the text off the displayed views (have to make them non-private in the binding class):
intent.putExtra("title", binding.title.text.toString())
intent.putExtra("code", binding.code.text.toString())
If you need to pass the entire object or most of its properties, you can add the library
implementation 'com.google.code.gson:gson:2.8.5' //Maybe the version is not the most recent, I just copied and pasted the implementation from the internet
And convert your object to a Json and pass it as a string
intent.putExtra("data", Gson().toJson(data))
and to receive it
val data = intent.getStringExtra("data", null)?.let {
Gson().fromJson(it, Results::Java.class)
}

How to change Activity when clicking an item of my RecyclerView?

I have a RecyclerView that gets information from FirebaseFirestore, I need that when I click on an item I change the activity and add a putExtra. I try to call an Intent inside the Adapter of my RecyclerView but I get the error 'Function declaration must have a name' and 'Expecting member declaration'.
How can I change the Activity and add a putExtra by clicking on an Item in the RecyclerView?
this is MyAdapter
package com.example.atipicoapp
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.core.content.ContextCompat.startActivity
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.list_item.view.*
class MyAdapter(private val platoList : ArrayList<Plato>,
private val itemClickListener: OnPlatoClickListener
) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
interface OnPlatoClickListener{
fun onItemClick(nombre: String)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter.MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
itemView.platoTouch.setOnClickListener(View.OnClickListener { v: View ->
})
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyAdapter.MyViewHolder, position: Int) {
val plato : Plato = platoList[position]
holder.platoName.text = plato.platoName
holder.platoDescription.text = plato.platoDescription
holder.platoPrecio.text = plato.platoPrecio.toString()
holder.platoCantidad.text = plato.platoCantidad.toString()
}
override fun getItemCount(): Int {
return platoList.size
}
public class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val platoName : TextView = itemView.findViewById(R.id.platoNombre)
val platoDescription : TextView = itemView.findViewById(R.id.platoDescripcion)
val platoPrecio : TextView = itemView.findViewById(R.id.platoPrecio)
val platoCantidad : TextView = itemView.findViewById(R.id.platoCant)
platoCantidad.setOnClickListener(View.OnClickListener {
val intent = Intent(itemView.getContext(),SlotActivity::class.java)itemView.getContext().startActivity(intent)})
}
}
You're getting an error here because you have two lines of code jammed together on one line.
val intent = Intent(itemView.getContext(),SlotActivity::class.java)itemView.getContext().startActivity(intent)})
A better way to handle this is to expose your click as a listener that the Activity (or Fragment) can implement. It would be more versatile if you change your listener function to use the item type as the parameter instead of a name String explicitly, so I would change it like this. Also, if you mark it as a fun interface, you can use more concise syntax when you define it in your Activity.
fun interface OnPlatoClickListener{
fun onItemClick(item: Plato)
}
Then in your view holder, add a parameter for the item so the click listener you put on your view can pass the item to the Activity's OnPlatoClickListener. Mark the view holder class as inner so it has access to the itemClickListener property of the adapter.
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var item: Plato? = null
val platoName : TextView = itemView.findViewById(R.id.platoNombre)
val platoDescription : TextView = itemView.findViewById(R.id.platoDescripcion)
val platoPrecio : TextView = itemView.findViewById(R.id.platoPrecio)
val platoCantidad : TextView = itemView.findViewById(R.id.platoCant)
// maybe you should set this on itemView instead so the whole row is clickable
platoCantidad.setOnClickListener {
item?.let(itemClickListener::onItemClick)
}
}
In onBindViewHolder you need to pass the item to the holder:
override fun onBindViewHolder(holder: MyAdapter.MyViewHolder, position: Int) {
val plato : Plato = platoList[position]
with(holder) {
item = plato
platoName.text = plato.platoName
platoDescription.text = plato.platoDescription
platoPrecio.text = plato.platoPrecio.toString()
platoCantidad.text = plato.platoCantidad.toString()
}
}
Then in your Activity (or Fragment), you can set a listener on the adapter when you create it:
val adapter = MyAdapter(theDataList) { clickedItem ->
val name = clickedItem.platoName
val intent = Intent(this#YourActivityName, SlotActivity::class.java)
// do something with name and intent?...
startActivity(intent)
}
// ...
override fun onBindViewHolder(holder: MyAdapter.MyViewHolder, position: Int) {
when (holder) {
is MyViewHolder -> {
holder.bind(platoList[position])
}
}
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val platoName : TextView = itemView.findViewById(R.id.platoNombre)
val platoDescription : TextView = itemView.findViewById(R.id.platoDescripcion)
val platoPrecio : TextView = itemView.findViewById(R.id.platoPrecio)
val platoCantidad : TextView = itemView.findViewById(R.id.platoCant)
private val mActivity = itemView.context as Activity
private val intent = Intent(mActivity, SlotActivity::class.java)
fun bind(plato: Plato) {
platoName.text = plato.platoName
platoDescription.text = plato.platoDescription
platoPrecio.text = plato.platoPrecio.toString()
platoCantidad.text = plato.platoCantidad.toString()
platoCantidad.setOnClickListener {
intent.putExtra("key", value)
mActivity.startActivity(intent)
}
}
}
Note: it is much better to use English in variable names and comments so that developers who read your code later can easily understand it.

(KOTLIN) Expanding and Collapsing in Expandable recyclerview

Objective
I want to expand new items in a RecyclerView at the same time, and the old selected items will be automatically collapsed.
What I done, it can be like this >>
The items expand and collapse on click but do not automatically collapse if another item is expanded
image1
Actually, what I want to make it like this >>
Any expanded item should be automatically collapse when another item is expanded.
image2
What I had researched
From this stack overflow had done what I want, but I don't how to convert into Kotlin, basically as I know it store the previous position then compare to the current position, through the If-Else Statement to determine and perform the action.
There are one more stack overflow, it also from java, slightly understand, briefly know the whole concept, but cannot go deeply explain for myself line-by-line.
This Github Sample is pretty matched my needs, but code styling quite complicated, and not fexible enough for me to add other feature and design.
Question
Why the previousPosition need to be -1?
How should separate currentPosition and previousPosition, and store the previousPosition to different object and value?
If the previousPosition is workable, how should I implement into my project?
If available, can share any related resources to me?
 like: screen shot the part of sample code, or other resources
Code
product_list_item.kt
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
import com.google.android.material.floatingactionbutton.FloatingActionButton
import org.json.JSONArray
import org.json.JSONObject
class ViewPartActivity : AppCompatActivity() {
private lateinit var newRecylerview : RecyclerView
private lateinit var newArrayList : ArrayList<Product>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view_part)
val btnInsertView: FloatingActionButton = findViewById(R.id.btnInsertView)
btnInsertView.setOnClickListener {
val insertViewIntent = Intent(this, AddPartActivity::class.java)
startActivity(insertViewIntent)
}
getData()
}
private fun getData() {
val url = "WEBAPI"
val requestQueue: RequestQueue = Volley.newRequestQueue(this)
val jsonObjectRequest: JsonObjectRequest = JsonObjectRequest(Request.Method.GET, url, null,
{ response ->
val jsonArray: JSONArray = response.getJSONArray("tbl_product")
val namelist = ArrayList<String>()
val categorylist = ArrayList<String>()
val quantitylist = ArrayList<String>()
val pricelist = ArrayList<String>()
for (x in 0 until jsonArray.length()) {
val jsonObject: JSONObject = jsonArray.getJSONObject(x)
val name: String = jsonObject.getString("NAME")
val category: String = jsonObject.getString("CATOGORYID")
val quantity: String = jsonObject.getString("QUANTITY")
val price: String = jsonObject.getString("PRICE")
namelist.add(name)
categorylist.add(category)
quantitylist.add(quantity)
pricelist.add(price)
}
newRecylerview =findViewById(R.id.recyclerView)
newRecylerview.layoutManager = LinearLayoutManager(this)
newRecylerview.setHasFixedSize(true)
newArrayList = arrayListOf<Product>()
for(i in namelist.indices){
val product = Product(namelist[i],categorylist[i],quantitylist[i],pricelist[i])
newArrayList.add(product)
}
val adapter = ProductAdapter(newArrayList)
newRecylerview.adapter = adapter
}, { error ->
Toast.makeText(this, error.message, Toast.LENGTH_LONG).show()
})
requestQueue.add(jsonObjectRequest)
}
}
ProductAdapter.kt
class ProductAdapter(private val productList : ArrayList<Product>) : RecyclerView.Adapter<ProductAdapter.MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.product_list_item, parent,false)
return MyViewHolder(itemView)
}
#SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = productList[position]
holder.tvProductName.text = currentItem.name
holder.tvProductCategory.text= currentItem.category
holder.tvProductQuantity.text=currentItem.quantity
holder.tvProductPrice.text= "RM "+currentItem.price
val isVisible : Boolean = currentItem.visibility
holder.constraintLayout.visibility = if (isVisible) View.VISIBLE else View.GONE
holder.tvProductName.setOnClickListener{
currentItem.visibility =!currentItem.visibility
notifyItemChanged(position)
}
}
override fun getItemCount(): Int {
return productList.size
}
class MyViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
val tvProductName: TextView = itemView.findViewById(R.id.productName)
val tvProductCategory : TextView = itemView.findViewById(R.id.productCategory)
val tvProductQuantity : TextView = itemView.findViewById(R.id.productQuantity)
val tvProductPrice : TextView = itemView.findViewById(R.id.productPrice)
val constraintLayout : ConstraintLayout = itemView.findViewById(R.id.expandedLayout)
}
}
Product.kt
data class Product(
var name: String, var category: String, var quantity: String, var price: String, var visibility: Boolean = false
)
Promise
Once I get the solution, I would try my best to explain the code more deeply and update at here.

I am making a project where User API call and fetch the data and display in recycler view

This is the code in which api is call and fetch the data and display in recyler view data and data1 are the deatils of api data but when I am launching the app it is showing blank screen. I want to make a network call using Retrofit, and fetch the list. (URL to fetch the user list https://reqres.in/api/users?page=2)
and then In a RecyclerView in the user list will be shown
Please help and tell what is wrong in the code.
User Adapter
package com.example.userlisttest.Adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.example.userlisttest.Model.Data
import com.example.userlisttest.R
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.item_view.view.*
class UserAdapter(private val context: Context): RecyclerView.Adapter<UserAdapter.MyViewHolder>() {
private val dataList = ArrayList<Data>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
var itemView = LayoutInflater.from(context).inflate(R.layout.item_view, parent, false)
return MyViewHolder(itemView)
}
override fun getItemCount(): Int {
return dataList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
// holder.image = dataList.get(position)
Picasso.get().load(dataList[position].avatar)
val data = dataList[position]
val userfullname = holder.itemView.full_name
val image = holder.itemView.avatar
val fullname = "$(data.firstname) $(data.lastname)"
userfullname.text = (fullname as TextView).toString()
Picasso.get().load(data.avatar).into(image)
holder.itemView.setOnClickListener() {
Toast.makeText(context, fullname, Toast.LENGTH_SHORT).show()
}
}
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var image: ImageView? = null
var text: TextView? = null
init {
image = itemView.findViewById(R.id.avatar)
text = itemView.findViewById(R.id.full_name)
}
}
}
Retrofit
package com.example.userlisttest.Retrofit.RetrofitClass
import com.example.userlisttest.Model.Data1
import com.google.gson.GsonBuilder
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
object RetrofitClient{
private val BASE_URL = "https://reqres.in/api/users?page=2"
private var retrofit:Retrofit?=null
fun getApiClient(baseUrl:String): Retrofit {
val gson = GsonBuilder()
.setLenient()
.create()
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}
return retrofit!!
}
}
Interface
package com.example.userlisttest.Retrofit.RetrofitClass
import com.example.userlisttest.Model.Data
import com.example.userlisttest.Model.Data1
import retrofit2.http.GET
interface RetrofitService {
#GET("users")
fun getUserList(): List<Data>
fun UserList(): List<Data1>
}
Data
package com.example.userlisttest.Model
import com.google.gson.annotations.SerializedName
data class Data1 (
#SerializedName("data")
val data: List<Data>? = null,
#SerializedName("page")
val page:Int = 0,
#SerializedName("perpage")
val perpage:Int = 0,
#SerializedName("total")
val total:Int = 0,
#SerializedName("totalpage")
val totalPage:Int = 0
)
Data
package com.example.userlisttest.Model
import com.google.gson.annotations.SerializedName
data class Data (
#SerializedName("id")
val id:Int,
#SerializedName("email")
val email:String,
#SerializedName("firstname")
val firstname : String,
#SerializedName("lastname")
val lastname: String,
#SerializedName("avatar")
val avatar: String,
)
MainActivity
class MainActivity : AppCompatActivity() {
private val dataList = ArrayList<Data>()
// private lateinit var adapter: UserAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
val adapter = UserAdapter(this)
val recyclerView: RecyclerView = findViewById(R.id.userList)
// adapter = UserAdapter(context)
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter
}
}
you should call the users api and then pass the data to the adapter
You are not making the request to fetch the data from the source (https://reqres.in/api/users?page=2).
You need to fetch the data using retrofit and pass it to the UserAdapter otherwise the arrayList used in the Adapter will be always empty.

Categories

Resources