EditText не фильтрует список RecyclerView в Android Kotlin - PullRequest
0 голосов
/ 27 февраля 2020

Я пытаюсь отфильтровать список в RecyclerView по EditText. В Activity передается ответ в объект адаптера, получаемый из класса ViewModel. А в адаптере написан метод фильтра. В целом фильтр поиска из EditText не работает. Ниже написан код, я не уверен, как я могу решить эту проблему.

Проект, имеющий мужественный файл Activity, Adapter, XML и класс ViewModel.

frag_availabletender

Эта страница имеет 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"
        />

Класс модели Этот класс имеет модель

   data class TenderProperty(

    val id: String,
    @Json(name = "img_src") val imgSrcUrl: String,
    val type: String,
    val price: Double
    )

ViewModel Здесь ответ получает

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())
        }
    }
}

Это класс адаптера

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()

        }
    }}}

Это занятие

 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) {

        }
    })
}}

1 Ответ

0 голосов
/ 27 февраля 2020

Я не использую фильтр в адаптере, но я думаю, что вы можете использовать list.filter и установить NewData с DiffUtil? хотя это может быть не лучшим решением

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...