I have a RecyclerView in MVVM project. I have to get text from editText (searchWordEt) and then pass it to the function that invokes API method in viewmodel.API works fine and returns data. But when I invoke searchDefAdapter.submitList(response) in SearchFragment nothing happens and RecyclerView data not showing.
class SearchDefAdapter(
private var infoListener: OnItemClickListener,
private var addListener: OnItemClickListener
):
ListAdapter<Def, SearchDefViewHolder>(differCallback) {
interface OnItemClickListener {
fun onItemClick(position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchDefViewHolder {
return SearchDefViewHolder(
SearchWordCardBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
),
addListener,
infoListener
)
}
override fun onBindViewHolder(holder: SearchDefViewHolder, position: Int) {
holder.bind(getItem(position))
}
}
class SearchDefViewHolder(
private val binding: SearchWordCardBinding,
addListener: SearchDefAdapter.OnItemClickListener,
infoListener: SearchDefAdapter.OnItemClickListener
): RecyclerView.ViewHolder(binding.root) {
fun bind(data: Def) {
with (binding) {
searchCardTv.text = "${data.text} - ${data.tr[0].text}"
}
}
init {
binding.addSearchCard.setOnClickListener {
addListener.onItemClick(adapterPosition)
}
binding.infoSearchCard.setOnClickListener {
infoListener.onItemClick(adapterPosition)
}
}
}
val differCallback = object : DiffUtil.ItemCallback<Def>() {
override fun areItemsTheSame(oldItem: Def, newItem: Def): Boolean {
return oldItem.text == newItem.text
}
override fun areContentsTheSame(oldItem: Def, newItem: Def): Boolean {
return oldItem == newItem
}
}
#AndroidEntryPoint
class SearchFragment : Fragment() {
private var _binding: FragmentSearchBinding? = null
private val binding get() = _binding!!
lateinit var searchDefAdapter: SearchDefAdapter
private val viewModel: DictionaryViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentSearchBinding.inflate(inflater, container, false)
val view = binding.root
searchDefAdapter = SearchDefAdapter(
object : SearchDefAdapter.OnItemClickListener {
override fun onItemClick(position: Int) {
Log.d("tag", "Item Added!")
//viewModel.saveWord(position)
}
},
object : SearchDefAdapter.OnItemClickListener {
override fun onItemClick(position: Int) {
val wordFragment = WordFragment()
fragmentManager?.beginTransaction()?.replace(
R.id.nav_host_fragment_container,
wordFragment
)?.commit()
}
}
)
setUpRecyclerView(searchDefAdapter)
var job: Job? = null
binding.searchWordEt.addTextChangedListener { editable ->
job?.cancel()
job = MainScope().launch {
delay(SEARCH_WORD_TIME_DELAY)
editable?.let {
if (editable.toString().isNotEmpty())
viewModel.getTranslation(editable.toString())
}
}
}
viewModel.def.observe(viewLifecycleOwner, Observer { response ->
binding.apply {
searchDefAdapter.submitList(response)
}
})
return view
}
override fun onDestroyView() {
_binding = null
super.onDestroyView()
}
private fun setUpRecyclerView(adapter: SearchDefAdapter){
binding.searchRv.apply {
adapter
layoutManager = LinearLayoutManager(activity)
}
}
}
You haven't actually set the adapter in setUpRecyclerView()
private fun setUpRecyclerView(myAdapter: SearchDefAdapter){
binding.searchRv.apply {
layoutManager = LinearLayoutManager(activity)
adapter = myAdapter // here
}
}
Related
First of all, I am Spanish so my english is not very good.
I have a list of items on a Recyclerview, and I also have a SearchView to filter those items.
Every item has a favourite button, so when you click, the item adds to favorite table.
The problem is that, when I filter something and I start clicking those buttons, odd things happens: some items dissapear from the filtered list. It doesn't happen always, only sometimes. How can I fix this?
My class:
class CoasterFragment : Fragment() {
private val myAdapter by lazy { CoasterRecyclerViewAdapter(CoasterListenerImpl(requireContext(), viewModel),requireContext()) }
private lateinit var searchView: SearchView
private var _binding: FragmentCoasterBinding? = null
private val binding get() = _binding!!
private val viewModel: CoastersViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentCoasterBinding.inflate(inflater, container, false)
val root: View = binding.root
val recyclerView = binding.recyclerCoaster
recyclerView.adapter = myAdapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
viewModel.coasters().observe(viewLifecycleOwner){myAdapter.setData(it)}
searchView = binding.search
searchView.clearFocus()
searchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
if(query != null){
searchDatabase(query)
searchView.clearFocus()
}
return true
}
override fun onQueryTextChange(query: String?): Boolean {
if(query != null){
searchDatabase(query)
}
return true
}
})
return root
}
fun searchDatabase(query: String) {
val searchQuery = "%$query%"
viewModel.searchDatabase(searchQuery).observe(viewLifecycleOwner) { myAdapter.setData(it)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
My adapter:
class CoasterRecyclerViewAdapter( val listener: CoasterListener,
val context: Context ) : RecyclerView.Adapter<CoasterRecyclerViewAdapter.ViewHolder>(){
private var coasterList = emptyList<CoasterFavorito>()
class ViewHolder private constructor(val binding: CoasterItemBinding, private val listener: CoasterListener,
private val context: Context): RecyclerView.ViewHolder(binding.root){
companion object{
fun crearViewHolder(parent: ViewGroup, listener: CoasterListener, context: Context):ViewHolder{
val layoutInflater = LayoutInflater.from(parent.context)
val binding = CoasterItemBinding.inflate(layoutInflater, parent, false)
return ViewHolder(binding, listener, context )
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder.crearViewHolder(parent, listener, context)
override fun onBindViewHolder(holder: ViewHolder, position: Int){
holder.binding.nombre.text = coasterList[position].coaster.nombre
holder.binding.parque.text = coasterList[position].coaster.parque
holder.binding.ciudad.text = coasterList[position].coaster.ciudad
holder.binding.provincia.text = coasterList[position].coaster.provincia
holder.binding.comunidad.text = coasterList[position].coaster.comunidadAutonoma
Glide
.with(context)
.load(coasterList[position].coaster.imagen)
.centerCrop()
.into(holder.binding.imagen)
holder.binding.check.isChecked = coasterList[position].favorito
holder.binding.check.setOnClickListener{
if (coasterList[position].favorito) {
listener.delFavorito(coasterList[position].coaster.id)
holder.binding.check.isChecked = false
} else {
listener.addFavorito(coasterList[position].coaster.id)
holder.binding.check.isChecked = true
}
}
}
override fun getItemCount(): Int{
return coasterList.size
}
fun setData(coaster: List<CoasterFavorito>){
coasterList = coaster
notifyDataSetChanged()
}
}
interface CoasterListener {
fun addFavorito(id: Long)
fun delFavorito(id: Long)
}
I tried changing the focus, changing the notifydatasetchanged with notifyitemchanged, and nothing happens...
My App is just shows an Empty Screen and RecyclerView is not showing anything or is not working but there are no compile time or run time errors.
It would be great help if I get an answer ...
I have been making an app that uses a RecyclerView but it's not showing any thing..why contents of the recycler view have not been showing up.my codes are bellow
Here is My FeedFragment, Adapter
//Fragment
#AndroidEntryPoint
class FeedFragment : Fragment(R.layout.feed_fragment) {
private var _binding: FeedFragmentBinding? = null
private val binding get() = _binding!!
private lateinit var feedAdapter: FeedAdapter
private val viewModel: FeedViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FeedFragmentBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupRv()
getCharacters()
}
private fun getCharacters() {
viewModel.listData.observe(viewLifecycleOwner, Observer { pagingData ->
feedAdapter.submitData(viewLifecycleOwner.lifecycle, pagingData)
})
}
private fun setupRv() {
feedAdapter = FeedAdapter()
binding.feedRv.layoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
binding.feedRv.apply {
adapter = feedAdapter
setHasFixedSize(true)
visibility = View.VISIBLE
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
//PagingDataAdapter
class FeedAdapter : PagingDataAdapter<Characters,FeedAdapter.FeedViewHolder >(DiffCallback()) {
inner class FeedViewHolder(private val binding: FeedFragmentRvBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(characters: Characters) {
with(binding) {
Glide.with(itemView)
.load(characters.image)
.transition(DrawableTransitionOptions.withCrossFade())
.error(R.drawable.ic_launcher_background)
.into(feedRvImage)
feedRvName.text = characters.name
feedRvStatus.text = characters.status
feedRvSpecies.text = characters.species
feedRvGender.text = characters.gender
println(characters.name)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FeedViewHolder {
val binding =
FeedFragmentRvBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return FeedViewHolder(binding)
}
override fun onBindViewHolder(holder: FeedViewHolder, position: Int) {
getItem(position)?.let { holder.bind(it) }
}
class DiffCallback : DiffUtil.ItemCallback<Characters>() {
override fun areItemsTheSame(oldItem: Characters, newItem: Characters): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Characters, newItem: Characters): Boolean {
return oldItem == newItem
}
}
}
// retrofit response
Update your CharacterResponse model class to parse data accordingly.
data class CharacterResponse(
val info: Info,
val results: List<Characters>
)
I am following this article here.
All is working well but now I want to implement the onclicklistener for each item.
Here's my code:
SongViewModelAdapter.kt
class SongViewModelAdapter(private val onSelect: ((ViewModelLyric?) -> Unit)?) : PagingDataAdapter<ViewModelLyric,
SongViewModelAdapter.SongViewHolder>(Companion) {
val TAG = "SongViewModelAdapter"
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val dataBinding = LyricDataBinding.inflate(
layoutInflater,
parent,
false
)
return SongViewHolder(dataBinding)
}
override fun onBindViewHolder(holder: SongViewHolder, position: Int) {
val lyric = getItem(position) ?: return
holder.bindLyric(lyric, onSelect)
}
companion object : DiffUtil.ItemCallback<ViewModelLyric>() {
override fun areItemsTheSame(oldItem: ViewModelLyric, newItem: ViewModelLyric): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: ViewModelLyric, newItem: ViewModelLyric): Boolean {
return oldItem == newItem
}
}
inner class SongViewHolder(
private val dataBinding: LyricDataBinding
) : RecyclerView.ViewHolder(dataBinding.root) {
fun bindLyric(lyric: ViewModelLyric, onSelect: ((ViewModelLyric?) -> Unit)?) {
dataBinding.itemTitle.text = lyric.title
dataBinding.itemArtist.text = lyric.artist
dataBinding.root.setOnClickListener {
onSelect?.let { it1 -> it1(lyric) }
}
}
}
}
HomeFragment.kt
#AndroidEntryPoint
class HomeFragment : Fragment() {
val TAG = "HomeFragment"
private lateinit var binding : FragmentHomeBinding
private val viewModel by viewModels<HomeFragmentViewModel>()
private var adapter = SongViewModelAdapter(null)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(
inflater, R.layout.fragment_home, container, false)
binding.productsRecyclerView.adapter = SongViewModelAdapter(::onSelect)
return binding.root
}
private fun onSelect(viewModelLyric: ViewModelLyric?) {
val id = viewModelLyric?.id
val bundle = bundleOf("id" to id)
Log.d(TAG, id.toString())
view?.findNavController()?.navigate(R.id.songDetailFragment, bundle)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setLyricsAdapter()
getLyrics()
setProgressBarAccordingToLoadState()
}
private fun setLyricsAdapter() {
binding.productsRecyclerView.adapter = adapter
}
private fun getLyrics() {
lifecycleScope.launch {
viewModel.flow.collectLatest {
adapter.submitData(it)
}
}
}
private fun setProgressBarAccordingToLoadState() {
lifecycleScope.launch {
adapter.loadStateFlow.collectLatest {
binding.progressBar.isVisible = it.append is LoadState.Loading
}
}
}
}
I am using FirestorePagingAdapter at the moment and it works well. For those experienced in paging 3, how would you pass total items to implement the click listener for each item. Saw similar questions but never a clear solution. Been scratching my head for a day. Your help will be much appreciated.
Edit 1: Added HomeFragment.kt
Edit 2: Updated with user suggestions. Click still not working. I needed to add the null checks.
It is not a good practice to handle click inside your adapter.
The adapter concern is just to act as a bridge b/w our data and the recyclerview not to handle click. Passing it back to fragment/activity restores that. Second, using callbacks may lead to Memory leaks as it going to have the reference to the fragment/activity.
class YourRecyclerViewAdapter(private val onSelect: (ViewModelLyric?) -> Unit) : PagingDataAdapter<ViewModelLyric, SongViewModelAdapter.SongViewHolder>(Companion) {
override fun onBindViewHolder(holder: YourViewHolder, position: Int) {
val lyric = getItem(position) ?: return
holder.bindLyric(lyric)
}
class SongViewHolder(private val binding: YourViewBinding) : RecyclerView.ViewHolder(dataBinding.root) {
fun bindLyric(yourDataType: ViewModelLyric?, onSelect: (ViewModelLyric?) -> Unit) {
dataBinding.itemTitle.text = lyric.title
dataBinding.itemArtist.text = lyric.artist
dataBinding.root.setOnClickListener {
onSelect(yourDataType)
}
}
}
}
In your Fragment/Activity
// Set this adapter to your recycler view
binding.productsRecyclerView.adapter = YourRecyclerViewAdapter { viewModelLyric->
// Handle click here
}
EDIT:
SongViewModelAdapter
class SongViewModelAdapter(private val onSelect: (ViewModelLyric) -> Unit) : PagingDataAdapter<ViewModelLyric, SongViewModelAdapter.SongViewHolder>(Companion) {
val TAG = "SongViewModelAdapter"
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val dataBinding = LyricDataBinding.inflate(layoutInflater, parent, false)
return SongViewHolder(dataBinding)
}
override fun onBindViewHolder(holder: SongViewHolder, position: Int) {
val lyric = getItem(position) ?: return
holder.bindLyric(lyric, onSelect)
}
companion object : DiffUtil.ItemCallback<ViewModelLyric>() {
override fun areItemsTheSame(oldItem: ViewModelLyric, newItem: ViewModelLyric): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: ViewModelLyric, newItem: ViewModelLyric): Boolean {
return oldItem == newItem
}
}
class SongViewHolder(private val dataBinding: LyricDataBinding) : RecyclerView.ViewHolder(dataBinding.root) {
fun bindLyric(lyric: ViewModelLyric, onSelect: (ViewModelLyric) -> Unit)) {
dataBinding.itemTitle.text = lyric.title
dataBinding.itemArtist.text = lyric.artist
dataBinding.root.setOnClickListener {
onSelect(lyric)
}
}
}
}
HomeFragment
#AndroidEntryPoint
class HomeFragment : Fragment() {
val TAG = "HomeFragment"
private lateinit var binding : FragmentHomeBinding
private val viewModel by viewModels<HomeFragmentViewModel>()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
binding.productsRecyclerView.adapter = SongViewModelAdapter(::onSelect)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
getLyrics()
setProgressBarAccordingToLoadState()
}
private fun onSelect(lyric: ViewModelLyric) {
// handle click here
}
private fun getLyrics() {
lifecycleScope.launch {
viewModel.flow.collectLatest {
binding.adapter.submitData(it)
}
}
}
private fun setProgressBarAccordingToLoadState() {
lifecycleScope.launch {
adapter.loadStateFlow.collectLatest {
binding.progressBar.isVisible = it.append is LoadState.Loading
}
}
}
}
I make an api call to get a list, in the logcat I can see all the groups that came back from the api but the Recylerview doesn't show my items.
ViewModel
class MyGroupScreenViewMode(private val context: Context, private val codagramApi: CodagramApi) : ViewModel() {
#ExperimentalCoroutinesApi
private val myGroups = MutableLiveData<List<Group>>()
#ExperimentalCoroutinesApi
fun getMyGroups(): LiveData<List<Group>> = myGroups
init {
viewModelScope.launch(Dispatchers.IO){
val response = codagramApi.getAllGroups()
updateUi(response.groupList)
}
}
#ExperimentalCoroutinesApi
private fun updateUi(update: List<Group>){
viewModelScope.launch(Dispatchers.Main){
myGroups.value = update
}
}
and the fragment
class MyGroupScreen : Fragment() {
private val myGroupsAdapter: GroupAdapter by inject()
private lateinit var bindingGroup: FragmentThirdBinding
#ExperimentalCoroutinesApi
private val viewModel: MyGroupScreenViewMode by inject()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
bindingGroup = FragmentThirdBinding.inflate(layoutInflater, container, false)
return bindingGroup.root
}
#ExperimentalCoroutinesApi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
bindingGroup.myGroups.apply {
adapter = this#MyGroupScreen.myGroupsAdapter
layoutManager = LinearLayoutManager(context)
}
myGroupsAdapter.currentList
bindingGroup.fabAdd.setOnClickListener {
it.findNavController().navigate(MyGroupScreenDirections.actionFirstViewToGroupscreen())
}
bindgetmyGroupToLiveData()
}
#ExperimentalCoroutinesApi
private fun bindgetmyGroupToLiveData() {
viewModel.getMyGroups().observe(viewLifecycleOwner, androidx.lifecycle.Observer {
myGroupsAdapter.submitList(it)
})
}
and the adapter
class GroupAdapter : ListAdapter<Group,GroupScreenViewHolder>(object: DiffUtil.ItemCallback<Group>(){
override fun areItemsTheSame(oldItem: Group, newItem: Group): Boolean = oldItem.creator?.id == newItem.creator?.id
override fun areContentsTheSame(oldItem: Group, newItem: Group): Boolean =
oldItem == newItem
}) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GroupScreenViewHolder {
return GroupScreenViewHolder(
GroupscreenMygroupsBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
#RequiresApi(Build.VERSION_CODES.N)
override fun onBindViewHolder(holder: GroupScreenViewHolder, position: Int) {
holder.bind(getItem(position))
}
}
class GroupScreenViewHolder(private val binding: GroupscreenMygroupsBinding) :
RecyclerView.ViewHolder(binding.root) {
#RequiresApi(Build.VERSION_CODES.N)
fun bind(postData: Group) {
binding.textView.text = postData.id.toString()
}
}
Check if data is in the list, then assign the list to adapter and call adapter.notifyDataSetChanged(),
SearchAdapter.kt
class SearchAdapter(ctx:Context,private val imageModelArrayList: ArrayList<SearchModel>) :
RecyclerView.Adapter<SearchAdapter.MyViewHolder>() {
private val inflater: LayoutInflater
private val arraylist: java.util.ArrayList<SearchModel>
init {
inflater = LayoutInflater.from(ctx)
this.arraylist = java.util.ArrayList<SearchModel>()
this.arraylist.addAll(MainActivity.imageModelArrayList)
}
override fun onBindViewHolder(holder: SearchAdapter.MyViewHolder, position: Int) {
holder.time.setText(imageModelArrayList[position].getOrders())
}
override fun getItemCount(): Int {
return imageModelArrayList.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchAdapter.MyViewHolder {
val view = inflater.inflate(R.layout.view_orderhistory, parent, false)
return MyViewHolder(view)
}
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var time: TextView
init {
time = itemView.findViewById(R.id.ordernumber) as TextView
}
}
fun filter(charText: String) {
var charText = charText
charText = charText.toLowerCase(Locale.getDefault())
MainActivity.imageModelArrayList.clear()
if (charText.length == 0) {
MainActivity.imageModelArrayList.addAll(arraylist)
} else {
for (wp in arraylist) {
if (wp.getOrders().toLowerCase(Locale.getDefault()).contains(charText)) {
MainActivity.imageModelArrayList.add(wp)
}
}
}
notifyDataSetChanged()
}
}
SearchModel.kt
class SearchModel {
var order: String? = null
private val image_drawable: Int = 0
fun getOrders(): String {
return order.toString()
}
fun setOrders(order: OrderHistory) {
this.order = order.toString()
}
}
I have written the code for populating the list. Code is running without any errors but my search functionality is not working.
MainActivity.kt
class MainActivity : AppCompatActivity(),SearchView.OnQueryTextListener {
private var recyclerView: RecyclerView? = null
private var adapter: SearchAdapter? = null
private var editsearch: SearchView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView=findViewById(R.id.listOfBookings) as? RecyclerView
imageModelArrayList = populateList()
Log.d("hjhjh", imageModelArrayList.size.toString() + "")
adapter = SearchAdapter(this, imageModelArrayList)
recyclerView?.adapter = adapter
recyclerView?.layoutManager = LinearLayoutManager(applicationContext, LinearLayoutManager.VERTICAL, false)
recyclerView?.addOnItemTouchListener(
RecyclerTouchListener(
applicationContext,
recyclerView!!,
object : ClickListener {
override fun onClick(view: View, position: Int) {
Toast.makeText(this#MainActivity, imageModelArrayList[position].getOrders(), Toast.LENGTH_SHORT)
.show()
}
override fun onLongClick(view: View?, position: Int) {
}
})
)
editsearch = findViewById(R.id.searchView) as SearchView
editsearch?.setOnQueryTextListener(this)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
adapter!!.filter(newText)
return false
}
private fun populateList(): ArrayList<SearchModel> {
val list = ArrayList<SearchModel>()
val xyz=HomeFragment().orderHistoryList
for (i in 0 until xyz.size-1) {
//var xyz=HomeFragment().orderHistoryList
var order=""
val imageModel = SearchModel()
imageModel.setOrders(xyz[i])
list.add(imageModel)
}
return list
}
interface ClickListener {
fun onClick(view: View, position: Int)
fun onLongClick(view: View?, position: Int)
}
internal class RecyclerTouchListener(
context: Context,
recyclerView: RecyclerView,
private val clickListener: ClickListener?
) : RecyclerView.OnItemTouchListener {
private val gestureDetector: GestureDetector
init {
gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapUp(e: MotionEvent): Boolean {
return true
}
override fun onLongPress(e: MotionEvent) {
val child = recyclerView.findChildViewUnder(e.x, e.y)
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child))
}
}
})
}
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
val child = rv.findChildViewUnder(e.x, e.y)
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildAdapterPosition(child))
}
return false
}
override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
}
}
companion object {
lateinit var imageModelArrayList: ArrayList<SearchModel>
}
}
In the HomeFragment I have the list(OrderHistoryList) which stores the order,status and date values. I am storing those list values in another list "ImageModelArrayList" for which i have written the functionality.
HomeFragment.kt
class HomeFragment : Fragment() {
private lateinit var orderHistoryViewModel: OrderHistoryViewModel
private lateinit var activityBinding: FragmentHomeBinding
var orderHistoryList:ArrayList<OrderHistory> = ArrayList()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return setupBindings(inflater, container, savedInstanceState)
}
private fun setupBindings(
inflater: LayoutInflater,
container: ViewGroup?, savedInstanceState: Bundle?
): View? {
//val activityBinding: FragmentHomeBinding = DataBindingUtil.setContentView(this.context as MainActivity, R.layout.fragment_home) as FragmentHomeBinding
activityBinding = FragmentHomeBinding.inflate(inflater, container, false)
orderHistoryViewModel = ViewModelProviders.of(this).get(OrderHistoryViewModel::class.java)
if (savedInstanceState == null) {
orderHistoryViewModel.init()
}
activityBinding.model = orderHistoryViewModel
setupListUpdate()
return (activityBinding as ViewDataBinding).root
}
fun setupListUpdate(){
orderHistoryViewModel.init()
orderHistoryViewModel.loading?.set(View.VISIBLE)
var orderHistoryDetails : OrderHistoryDetails = OrderHistoryDetails()
orderHistoryList.add(OrderHistory(order ="#102-AB-3045",status="Intransit",Date="11 Dec"))
orderHistoryList.add(OrderHistory(order ="#102-AB-3047",status="Delivered",Date="13 Dec"))
orderHistoryList.add(OrderHistory(order ="#102-AB-3048",status="Delivered",Date="12 Dec"))
orderHistoryList.add(OrderHistory(order ="#102-AB-3049",status="Delivered",Date="14 Dec"))
orderHistoryList.add(OrderHistory(order ="#102-AB-3056",status="Delivered",Date="16 Dec"))
orderHistoryList.add(OrderHistory(order ="#102-AB-3089",status="Delivered",Date="15 Dec"))
orderHistoryList.add(OrderHistory(order ="#102-AB-3090",status="Delivered",Date="17 Dec"))
orderHistoryDetails.orderHistoryList =orderHistoryList
orderHistoryDetails.orderList =MutableLiveData()
orderHistoryDetails.orderList?.value=orderHistoryDetails.orderHistoryList
orderHistoryDetails.orderList?.observe(this,
Observer<List<OrderHistory>> { bookings ->
orderHistoryViewModel.loading.set(View.GONE)
if (bookings.isEmpty()) {
orderHistoryViewModel.showEmpty.set(View.VISIBLE)
} else {
orderHistoryViewModel.showEmpty.set(View.GONE)
orderHistoryViewModel.setBookingsInAdapter(bookings)
}
})
orderHistoryViewModel.orderHistoryDetails=orderHistoryDetails
}
}
You can view these link its java guide but helpful for you
https://velmm.com/android-recyclerview-search-filter-example/
https://demonuts.com/recyclerview-search-filter/