I am trying to filter the list in RecyclerView by EditText. In Activity, passing the response in the adapter object, which is getting from the ViewModel class. And in the adapter, the filter method is written. Overall the Search Filter from EditText is not working. Below the code is written I am not sure how can I resolve this problem.
Project having manly an Activity,Adapter, XML file, and the ViewModel class.
fragment_availabletender
This page is having EditText & RecyclerView.
<EditText
android:id="@+id/editMobileNo"
android:layout_width="match_parent"
android:layout_height="50dp"
android:padding="0dp"
android:background="@drawable/login_edittext"
android:ems="10"
android:hint="Search Tender"
android:gravity="center"
android:drawableLeft="@drawable/search_3_24"
android:layout_below="@+id/tendertext"
android:paddingLeft="50dp"
>
</EditText>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tender_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:color="@color/cardview_light_background"
android:padding="6dp"
android:background="@null"
android:scrollbars="vertical"
android:layout_marginTop="10dp"
android:layout_below="@+id/text1"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
/>
Model Class This class is having model
data class TenderProperty(
val id: String,
@Json(name = "img_src") val imgSrcUrl: String,
val type: String,
val price: Double
)
ViewModel Here response is getting
class NotificationViewModel : ViewModel() {
val response: LiveData<List<TenderProperty>>
get() = _response
private var _responseByArray = ArrayList<TenderProperty>()
val responseByArray: List<TenderProperty>
get() = _responseByArray
private val _navigateToSelectedProperty = MutableLiveData<TenderProperty>()
val navigateToSelectedProperty: LiveData<TenderProperty>
get() = _navigateToSelectedProperty
// Create a Coroutine scope using a job to be able to cancel when needed
private var viewModelJob = Job()
private val coroutineScope = CoroutineScope(viewModelJob + Dispatchers.Main )
init {
getTenderRealEstateProperties()
}
private fun getTenderRealEstateProperties() {
coroutineScope.launch {
// Get the Deferred object for our Retrofit request
var getPropertiesDeferred = TenderApi.retrofitService.getProperties()
try {
// this will run on a thread managed by Retrofit
val listResult = getPropertiesDeferred.await()
_responseByArray= listResult as ArrayList<TenderProperty>
Log.d("respbyary",responseByArray.toString())
} catch (e: Exception) {
_response.value = ArrayList()
Log.d("class",responseByArray.toString())
}
}
}
This is the Adapter class
class ListTenderAdapter(context: Context, var tender: List<TenderProperty>) : ListAdapter<TenderProperty, ListTenderAdapter.TenderPropertyViewHolder>(DiffCallback),Filterable {
var originalData=tender
var filteredData = ArrayList<TenderProperty>()
//dought22
class TenderPropertyViewHolder(private var binding: TenderListViewBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(tenderProperty: TenderProperty) {
binding.property = tenderProperty
binding.executePendingBindings()
}
}
companion object DiffCallback : DiffUtil.ItemCallback<TenderProperty>()
{
override fun areItemsTheSame(oldItem: TenderProperty, newItem: TenderProperty): Boolean {
return oldItem === newItem
}
override fun areContentsTheSame(oldItem: TenderProperty, newItem: TenderProperty): Boolean {
return oldItem.id == newItem.id
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TenderPropertyViewHolder {
return TenderPropertyViewHolder(TenderListViewBinding.inflate(LayoutInflater.from(parent.context)))
}
override fun onBindViewHolder(holder: TenderPropertyViewHolder, position: Int) {
val tenderProperty = getItem(position)
holder.bind(tenderProperty)
}
override fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
var filteredList = ArrayList<TenderProperty>()
if (constraint.isNullOrBlank()) {
filteredData.addAll(originalData)
}
else {
for (data in originalData) {
if (
data.id.toLowerCase().contains(constraint.toString().toLowerCase())||
data.price.toString().toLowerCase().contains(constraint.toString().toLowerCase())||
data.type.toLowerCase().contains(constraint.toString().toLowerCase()))
{
filteredList.add(data)
} }
}
val filterResults = FilterResults()
filterResults.values = filteredList
return filterResults
}
override fun publishResults(constraint: CharSequence, results: FilterResults) {
filteredData.clear()
filteredData.addAll(results.values as ArrayList<TenderProperty>)
notifyDataSetChanged()
}
}}}
This is the Activity
class TenderListActivity:AppCompatActivity() {
lateinit var adapter: ListTenderAdapter
lateinit var search:EditText
private lateinit var binding: FragmentAvailabletenderBinding
private val viewModel: NotificationViewModel by lazy {
ViewModelProviders.of(this).get(NotificationViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_availabletender)
binding = DataBindingUtil.setContentView<FragmentAvailabletenderBinding>(
this,
R.layout.fragment_availabletender
)
search = binding.editMobileNo
val divider = DividerItemDecoration(applicationContext, DividerItemDecoration.VERTICAL)
binding.tenderList.addItemDecoration(divider)
setupRecyclerView()
initViewModel()
search()
backButton()
}
private fun setupRecyclerView() {
binding.tenderList.addItemDecoration(MarginItemDecoration(5))
adapter = ListTenderAdapter(this, viewModel.responseByArray)
binding.tenderList.setAdapter(adapter)
}
private fun initViewModel() {
viewModel.response.observe(this, Observer {
adapter.submitList(it)
})
}
private fun backButton()
{
binding.backbtn.setOnClickListener(View.OnClickListener {
val backbtn: Intent = Intent(this,MainActivity::class.java)
startActivity(backbtn)
})
}
private fun search()
{
search.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
adapter.getFilter().filter(s.toString())
}
override fun afterTextChanged(s: Editable) {
}
})
}}
i'm not use the filter in the adapter,but i think may be u can use the list.filter and setThe NewData with the DiffUtil? although it may be not the best solution
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.