How to make searchview works for find my dummy data

25 Views Asked by At

I got stuck, i making some searchview for find my dummy item but still didnt work, anyone know how it works ? this is my dummy data

interface DummyMateriDataSource {
    fun getMateriData(context:Context): List<Materi>
}

class DummyMateriDataSourceImpl() : DummyMateriDataSource {
    override fun getMateriData(context:Context): List<Materi> {

        return mutableListOf(
            Materi(
                imgUrl = "https://raw.githubusercontent.com/ryhanhxx/img_asset/main/img_kalkulator.webp",
                title = context.getString(R.string.title_materi_1),
                heading = context.getString(R.string.heading_materi_1),
                desc = context.getString(R.string.desc_materi_1),
                subHeading =  context.getString(R.string.subheading_materi_1),
                subDesc = context.getString(R.string.subdesc_materi_1),
                source = "https://keltunggulwulung.malangkota.go.id/2022/11/02/pengertian-dan-istilah-dalam-hukum-waris/"
            )
        )
    }
}

Heres my problem, i dont know how to make my searchview work for find my dummy data, i wanna find it when i type the title on searchview

class MateriFragment : Fragment() {

    private lateinit var binding: FragmentMateriBinding

    private val adapter: MateriAdapter by lazy {
        MateriAdapter(AdapterLayoutMode.LINEAR){ materi: Materi ->
            navigateToDetailFragment(materi)
        }
    }

    private val datasource: DummyMateriDataSource by lazy {
        DummyMateriDataSourceImpl()
    }

    private fun navigateToDetailFragment(materi: Materi) {
        MateriActivity.startActivity(requireContext(), materi)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentMateriBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setupList()
        setupSwitch()
    }

    private fun setSearchView(){
        //TODO: Searchview for dummy
    }

    private fun setupList() {
        val span = if(adapter.adapterLayoutMode == AdapterLayoutMode.LINEAR) 1 else 2
        binding.rvMateri.apply {
            layoutManager = GridLayoutManager(requireContext(),span)
            adapter = [email protected]
        }
        adapter.setItems(datasource.getMateriData(requireContext()))
    }

    private fun setupSwitch() {
        binding.swGrid.setOnCheckedChangeListener { _, isChecked ->
            (binding.rvMateri.layoutManager as GridLayoutManager).spanCount = if (isChecked) 2 else 1
            adapter.adapterLayoutMode = if(isChecked) AdapterLayoutMode.GRID else AdapterLayoutMode.LINEAR
            adapter.refreshList()
        }
    }
}

this is my MateriAdapter for my recycleview

class MateriAdapter (
    var adapterLayoutMode: AdapterLayoutMode,
    private val onClickListener: (Materi) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private val dataDiffer = AsyncListDiffer(this, object : DiffUtil.ItemCallback<Materi>() {
        override fun areItemsTheSame(oldItem: Materi, newItem: Materi): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Materi, newItem: Materi): Boolean {
            return oldItem.hashCode() == newItem.hashCode()
        }
    })

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            AdapterLayoutMode.GRID.ordinal -> (GridMateriViewHolder(
                binding = ItemCardGridBinding.inflate(
                    LayoutInflater.from(parent.context), parent, false
                ), onClickListener
            ))

            else -> {
                LinearMateriViewHolder(
                    binding = ItemCardListBinding.inflate(
                        LayoutInflater.from(parent.context), parent, false
                    ), onClickListener
                )
            }
        }
    }

    override fun getItemCount(): Int = dataDiffer.currentList.size

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        (holder as ViewHolderBinder<Materi>).bind(dataDiffer.currentList[position])
    }

    override fun getItemViewType(position: Int): Int {
        return adapterLayoutMode.ordinal
    }

    fun setItems(data: List<Materi>) {
        dataDiffer.submitList(data)
    }

    fun refreshList() {
        notifyItemRangeChanged(0, dataDiffer.currentList.size)
    }
}
1

There are 1 best solutions below

2
Eko Muhammad Rilo Pembudi On

firstly, try to add a function in MusicDataSource class to retrieve the data based on title

fun searchMusicByTitle(query: String): List<Music> {
    return getMusicData().filter { it.title.contains(query, ignoreCase = true) }
}

then update the searchView function like below

private fun setSearchView() {
    // Assuming you have a searchView with id searchView
    searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
        override fun onQueryTextSubmit(query: String?): Boolean {
            return false
        }

        override fun onQueryTextChange(newText: String?): Boolean {
            newText?.let {
                val filteredMusicList = if (it.isBlank()) {
                   // If query is empty, show all data
                   datasource.getMusicData(context)
                } else {
                   datasource.searchMusicByTitle(it)
                }
                adapter.setItems(filteredMusicList)
            }
            return true
        }
    })
}