This is the endpoint from server
@Headers("Accept: application/json")
@GET("markets?search=")
suspend fun searchItems(
@Header("Authorization") bearerToken: String,
@Query("") keyword: String
): Response<MarketAccessResponse>
this is the model and response
data class Market( val id: Int, val comodity_id: Int, val user_id: Int, val quantity: Int, val estimated_weight_unit_id: Int, val harvest_estimated_start: String, val harvest_estimated_end: String, val price: Int, val price_weight_unit_id: Int, val status: String, val company_name: String, val note: String, val address: String, val photo: String, val latitude: String, val longitude: String, val province_id: Int, val regency_id: Int, val district_id: Int, val village_id: BigInteger, val type: String, val createdAt: String?, val updatedAt: String?, val comodity : Comodity, val estimated_weight_unit : EstimatedWeightUnit, val price_weight_unit : PriceWeightUnit, val province : Provinsi, val regency : Regenci, val district : Distrik, val village : Village, )
class Comodity( val id: Int, val name: String, )
class EstimatedWeightUnit( val id: Int, val unit: String, )
class PriceWeightUnit( val id: Int, val unit: String, )
class Provinsi( val id: String, val name: String, )
class Regenci( val id: String, val name: String, )
class Distrik( val id: String, val name: String, )
class Village( val id: String, val name: String, )
data class MarketAccessResponse( val data: List, val message: String, val error: Boolean )
My Adapter Class
class MarketItemAdapter(private val items: List<Market> = mutableListOf())
: RecyclerView.Adapter<MarketItemAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val ivMarketAccess: ImageView = itemView.findViewById(R.id.img_market_access)
private val tvCompanyAccess: TextView = itemView.findViewById(R.id.tv_company_access)
private val tvProductMarket: TextView = itemView.findViewById(R.id.tv_product_market)
private val tvProductDescription: TextView = itemView.findViewById(R.id.tv_product_description)
private val tvProductLocation: TextView = itemView.findViewById(R.id.tv_product_location)
private val tvMarketStatus: TextView = itemView.findViewById(R.id.tv_market_status)
private val tvMarketStatusSuccess: TextView = itemView.findViewById(R.id.tv_market_status_success)
private val btnMarketStatusPending: ConstraintLayout = itemView.findViewById(R.id.btn_market_status_pending)
private val btnMarketStatusSuccess: ConstraintLayout = itemView.findViewById(R.id.btn_market_status_success)
private val btnFillDetail: LinearLayout = itemView.findViewById(R.id.btn_fill_Detail)
fun bind(item: Market) {
// Set the icon and name values for each item
Picasso.get()
.load(item.photo)
.placeholder(R.drawable.placeholder_potrait) // Placeholder image if the actual image is loading
.error(R.drawable.placeholder_potrait)
.fit().centerCrop()// Error image if Picasso fails to load the image
.into(ivMarketAccess)
tvCompanyAccess.text = item.company_name
tvProductMarket.text = item.comodity.name
tvProductDescription.text = "kebutuhan ${item.quantity} kg"
tvProductLocation.text = item.regency.name
tvMarketStatus.text = item.status
tvMarketStatusSuccess.text = item.status
if (tvMarketStatus.text == "tersedia") {
btnMarketStatusSuccess.isGone = false
btnMarketStatusPending.isGone = true
}
btnFillDetail.setOnClickListener {
val context = itemView.context
val i = Intent(context, DetailMarketActivity::class.java)
i.putExtra("img",item.photo)
i.putExtra("company-name",tvCompanyAccess.text)
i.putExtra("note",item.note)
i.putExtra("address",item.address)
i.putExtra("pruduct",tvProductMarket.text)
i.putExtra("stock",item.quantity.toString())
i.putExtra("datetime",item.createdAt)
i.putExtra("location",item.regency.name)
i.putExtra("available",tvMarketStatus.text)
i.putExtra("pending",tvMarketStatusSuccess.text)
context.startActivity(i)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_market_access, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(items[position])
}
override fun getItemCount(): Int {
return items.size
}
fun getItem(position: Int): Market {
return items[position]
}
fun setItems(newItems: List<Market>) {
// items.clear()
// items.addAll(newItems)
notifyDataSetChanged()
}
}
this is my activity
class MarketAccessActivity : AppCompatActivity() {
private lateinit var ivBack : ImageView
private lateinit var rvMarket: RecyclerView
private lateinit var adapter: MarketItemAdapter
private lateinit var searchView: SearchView
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_market_access)
ivBack = findViewById(R.id.iv_back)
ivBack.setOnClickListener {
startActivity(Intent(this@MarketAccessActivity, HomeActivity::class.java))
finish()
}
searchView = findViewById(R.id.searchView)
adapter = MarketItemAdapter()
rvMarket = findViewById(R.id.rv_market_access)
val layoutManager = GridLayoutManager(this, 2)
rvMarket.layoutManager = layoutManager
getMarketAccess()
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
searchItems(newText)
return false
}
})
}
private fun searchItems(keyword: String) {
// Retrieve tokens
val (savedToken, savedRefreshToken) = SharedPrefsUtil.getTokens(this@MarketAccessActivity)
if (savedToken != null && savedRefreshToken != null) {
CoroutineScope(Dispatchers.IO).launch {
val apiService = ApiClient.apiService.searchItems("Bearer $savedToken",keyword)
try {
if (apiService.isSuccessful) {
val items = apiService.body()?.data
runOnUiThread {
adapter.setItems(items.orEmpty())
rvMarket.adapter = adapter
}
Log.d("data-search", apiService.body().toString() )
}
} catch (e: Exception) {
e.printStackTrace()
Log.d("$e", keyword )
}
}
}
}
private fun getMarketAccess() {
// Retrieve tokens
val (savedToken, savedRefreshToken) = SharedPrefsUtil.getTokens(this@MarketAccessActivity)
if (savedToken != null && savedRefreshToken != null) {
// Show progress dialog
val progressDialog = ProgressDialog(this@MarketAccessActivity)
progressDialog.setMessage("Loading data...")
progressDialog.setCancelable(false)
progressDialog.show()
val call = ApiClient.apiService.getMarketList("Bearer $savedToken")
call.enqueue(object : Callback<MarketAccessResponse> {
override fun onResponse(call: Call<MarketAccessResponse>, response: Response<MarketAccessResponse>) {
progressDialog.dismiss() // Dismiss progress dialog on failure
if (response.isSuccessful) {
val marketResponse = response.body()
marketResponse?.let {
// TODO: Process the list of lands in landResponse.data
// For example, you can access the list using landResponse.data
val marketList = marketResponse.data
val marketAdapter = MarketItemAdapter(marketList)
rvMarket.adapter = marketAdapter
Log.d("data-muncul",response.body()?.data.toString())
}
} else {
// Handle API error here
// You can extract the error message from the response
// using response.errorBody()?.string()
Toast.makeText(this@MarketAccessActivity,
"Failed to fetch markets", Toast.LENGTH_SHORT).show()
Log.e("failed", "Failed fetch data")
}
}
override fun onFailure(call: Call<MarketAccessResponse>, t: Throwable) {
progressDialog.dismiss() // Dismiss progress dialog on failure
// Handle network or other errors here
Toast.makeText(this@MarketAccessActivity,
"Failed to fetch lands", Toast.LENGTH_SHORT).show()
Log.e("GetMarketsError", t.toString())
}
})
}
}
}
I can get a JSON response, but the overall data is not based on the query I entered.
In suspend fun searchItems()
of your code, there is a Query parameter that don’t have name specifier.
@Query("") keyword: String