using onQueryTextChange in fragment and need some suggestions regarding code
Actually I Wanna add SearchView in fragments Using Kotlin but nobody is telling how to do that so i was trying to use that code that used by YouTuber who was Creating Searchview in Activity.They were using a code after ForEach loop and that was if(it.lowercase(Locale.getDefault().contains(text).
So when i added this Line compiler Throwed Error that Unresolved Reference ,receiver type mismatch...so I just Wanna know what line Should i add instead of this (if i don't use this line then nothing add in my temp array)
thanks
Here is my Code :
...
Datahai class's code
class DataHai (
var book_id : String,
val name : String,
val author: String,
val price: String,
val rating : String,
var image: String
)
dashboard fragment
class Dashboard : Fragment() {
lateinit var recyclerView: RecyclerView // recycler view
lateinit var relativeLayout: RelativeLayout
lateinit var ada: adapter //adapter class object
lateinit var values: DataHai
lateinit var swipe: SwipeRefreshLayout
lateinit var LayoutManager: LinearLayoutManager
lateinit var value: ArrayList<DataHai>
lateinit var temp :ArrayList<DataHai>
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var view = inflater.inflate(R.layout.fragment_dashboard,
container, false)
value = ArrayList()
temp= ArrayList()
setHasOptionsMenu(true)
swipe = view.findViewById(R.id.swipe)
relativeLayout = view.findViewById(R.id.progresslaoout)
recyclerView = view.findViewById(R.id.recycler)
LayoutManager = LinearLayoutManager(activity)
gettingData()
swipe.setOnRefreshListener {
gettingData()
}
relativeLayout.visibility = View.VISIBLE
val que = Volley.newRequestQueue(activity as Context)
var url = "http://13.235.250.119/v1/book/fetch_books/"
var jsonObjectRequest =
object : JsonObjectRequest(Method.GET, url, null,
Response.Listener {
try {
relativeLayout.visibility = View.GONE
var success = it.getBoolean("success")
if (success) {
var data = it.getJSONArray("data")
for (i in 0 until data.length())
{
var jsonobject = data.getJSONObject(i)
values = DataHai(
// jsonobject.getString("book_id"),
jsonobject.getString("name"),
jsonobject.getString("author"),
jsonobject.getString("price"),
jsonobject.getString("rating"),
jsonobject.getString("image")
)
value.add(values)
//now am adding that data inside value array of Datahai class
}
temp.addAll(value)
} else {
makeText(context, "some error occured", Toast.LENGTH_SHORT).show()
}
// /* saying context == null*/
ada = adapter(activity as Context, temp)
/*now giving activity as context
and adding value array that will access by adapter
class array*/
recyclerView.adapter = ada
/* connecting these classes */
recyclerView.layoutManager = LayoutManager
} catch (e: JSONException) {
makeText(context, "some error occured",
Toast.LENGTH_SHORT).show()
}
}, Response.ErrorListener {
makeText(context, "some error occured",
Toast.LENGTH_SHORT).show()
}) {
override fun getHeaders(): MutableMap<String,
String> {
val header = HashMap<String, String>()
header.put("value-type", "application/json")
header.put("token", " 9bf534118365f1")
return header
}
}
que.add(jsonObjectRequest)
return view
}
fun gettingData() {
if (Connection().ConnectionChecking(activity as Context)) {
} else {
var build = AlertDialog.Builder(activity as Context)
build.setTitle("Not Connected")
build.setMessage("please check your internet
Connection")
build.setPositiveButton("try again") { text, listner ->
startActivityForResult(Intent(Settings.ACTION_WIRELESS_SETTINGS), 0)
}
build.setNegativeButton("cancel") { text, listner ->
}
build.create()
build.show()
}
swipe.isRefreshing = false
}
override fun onCreateOptionsMenu(menu: Menu, inflater:
MenuInflater) {
inflater.inflate(R.menu.icon,menu)
var item=menu.findItem(R.id.search)
var search=item?.actionView as SearchView
super.onCreateOptionsMenu(menu, inflater)
search.setOnQueryTextListener(object:SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(p0: String?): Boolean {
return true
}
override fun onQueryTextChange(p0: String?): Boolean {
temp.clear()
var text=p0?.lowercase(Locale.getDefault())
if (text!!.isNotEmpty()) {
makeText(activity as Context, "working",
Toast.LENGTH_LONG).show()
value.forEach {
temp.add(it) //by this line data should add
but not added
}
}
else {
temp.clear()
temp.addAll(value)
}
recyclerView.adapter?.notifyDataSetChanged()
return true
}
})
}
}
adapter
class adapter(var context : Context, var ada : ArrayList) : Adapter<adapter.viewholderclass>() {
/*array*/
override fun onCreateViewHolder(parent: ViewGroup, viewType:
Int): viewholderclass {
var view=
LayoutInflater.from(parent.context).inflate(R.layout.adapter,parent
,false)
return viewholderclass(view)
}
override fun onBindViewHolder(holder: viewholderclass,
position: Int) {
var id=ada[position]
var auth=ada[position]
/* now i am parsing the data from the ada array */
holder.author.text=auth.author
var nam=ada[position]
holder.year.text=nam.name
var rate=ada[position]
holder.rating.text=rate.rating
var pri=ada[position]
holder.price.text=pri.price
Picasso.get().load(id.image).into(holder.image)
}
override fun getItemCount() :Int{
return ada.size /* returning the size */
}
class viewholderclass(view: View) :
RecyclerView.ViewHolder(view) {
var year=view.findViewById<TextView>(R.id.name)
var author=view.findViewById<TextView>(R.id.author)
var rating=view.findViewById<TextView>(R.id.rating)
var price=view.findViewById<TextView>(R.id.price)
var image=view.findViewById<ImageView>(R.id.image)
var layout =view.findViewById<RelativeLayout>(R.id.adapter)
}
}
...
Solution 1:
From the original code in your question:
value.forEach {
if(it.lowercase(Locale.getDefault()).contains(searchtext)) {
temp.add(it)
}
}
Since value
is a list of Datahai
, then inside the lambda, it
is a Datahai, not a String, so you can't call lowercase
on it. You said in the comments you want to search the name
property only, so you only need to get the name
and compare that:
value.forEach {
if(it.name.lowercase(Locale.getDefault()).contains(searchtext)) {
temp.add(it)
}
}
Your code would be a little simpler using filterTo
instead of forEach
:
value.filterTo(temp) {
it.name.lowercase(Locale.getDefault()).contains(searchtext))
}