androidkotlinandroid-recyclerviewandroid-diffutilsandroid-asynclistdiffer

Remove AsyncListDiffer list and update it after click close search (submit null not working)


In this app I am using AsyncListDiffer I have a toolbar with searchBar and a search icon I am trying to remove the old search list when the user clicks on close search and make a new call request then submits the new one, it seems the submitList(null) called but the new value doesn't affect I see an empty screen

differCallback

    private val differCallback = object : DiffUtil.ItemCallback<Item>() {
        override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
            return (oldItem.id == newItem.id)
        }

        override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
          return (oldItem == newItem)
        }
    }

    val differ = AsyncListDiffer(this, differCallback)

the main requestApiData

private fun requestApiData() {
        showShimmerEffect()
        Log.d(TAG, "requestApiData: called")
        postViewModel.getPostListByLabel()
        postViewModel.postsResponse.observe(viewLifecycleOwner) { response ->
            postsAPiFlag = true
            when (response) {
                is NetworkResult.Success -> {
                    hideShimmerEffect()
                    response.data?.let {
                        binding.progressBar.visibility = View.GONE
                        adapter.differ.submitList(it.items.toList())
                    }

                }

                is NetworkResult.Error -> {
                    hideShimmerEffect()
                    binding.progressBar.visibility = View.GONE
                    //                    loadDataFromCache()
//                    Toast.makeText(
//                        requireContext(),
//                        response.message.toString(),
//                        Toast.LENGTH_LONG
//                    ).show()

                    Log.e(TAG, response.data.toString())
                    Log.e(TAG, response.message.toString())
                }

                is NetworkResult.Loading -> {
                    binding.progressBar.visibility = View.VISIBLE


                }
            }

        }
    }

search API method


    private fun requestSearchApi(keyword: String) {

        if (Utils.hasInternetConnection(requireContext())) {

//            postViewModel.getPosts().cancel()
            showShimmerEffect()

            postViewModel.finalURL.value =
                "${BASE_URL}?labels=Accessory&maxResults=500&key=$API_KEY"

            postViewModel.getItemsBySearch()
            postViewModel.searchedPostsResponse.observe(this) { response ->
                when (response) {
                    is NetworkResult.Success -> {
                        postsAPiFlag = false
                        //                                adapter.differ.currentList.clear()

                        if (searchItemList.isNotEmpty()) {
                            searchItemList.clear()
                        }

                        binding.progressBar.visibility = View.GONE

                        lifecycleScope.launch {
                            searchItemList = async {
                                response.data?.items?.filter {
                                    it.title.contains(keyword) || it.content.contains(keyword)
                                } as ArrayList<Item>
                            }.await()
                        }

                        Log.d(TAG, "requestSearchApi: test size ${searchItemList.size}")


                        if (searchItemList.isEmpty()) {
//                                adapter.differ.submitList(null)
                            Toast.makeText(
                                requireContext(),
                                "The search word was not found in any post",
                                Toast.LENGTH_SHORT
                            ).show()
                            hideShimmerEffect()
                            return@observe

                        } else {
                            postsAPiFlag = false

//                            adapter.differ.submitList(null)

                            binding.accessoryRecyclerView.removeAllViews()
                            binding.accessoryRecyclerView.recycledViewPool.clear()
                            hideShimmerEffect()

                            adapter.differ.submitList(searchItemList.toList())
//                            binding.accessoryRecyclerView.scrollToPosition(0)
                        }

                    }
                    is NetworkResult.Error -> {
                        hideShimmerEffect()
                        binding.progressBar.visibility = View.GONE
                        Toast.makeText(
                            requireContext(),
                            response.message.toString(),
                            Toast.LENGTH_SHORT
                        ).show()
                        Log.e(TAG, "onQueryTextSubmit: $response")

                    }

                    is NetworkResult.Loading -> {
                        binding.progressBar.visibility = View.VISIBLE

                    }
                }
            }
        } else {
            noInternetConnectionLayout()
        }
    }

searchView.setOnCloseListener

 searchView.setOnCloseListener {

            setOnCloseListenerFlag = true
            if (keyword.isNullOrEmpty()) {
                return@setOnCloseListener false
            }
            if (Utils.hasInternetConnection(requireContext())) {
                showShimmerEffect()

                searchItemList.clear()
                adapter.differ.submitList(null)
                postViewModel.postListResponse = null
                linearLayoutManager?.removeAllViews()

                postViewModel.finalURL.value =
                    BASE_URL_POSTS_BY_LABEL + "posts?labels=Accessory&key=$API_KEY"

                requestApiData() //====> Here I call the request api method again
//                adapter.notifyDataSetChanged()

                Log.d(
                    TAG,
                    "setOnCloseListener: called ${adapter.differ.currentList.size.toString()}"
                )
//                adapter.notifyDataSetChanged()
//                binding.progressBar.visibility = View.GONE
//


                Log.d(TAG, "setOnCloseListener: ${postViewModel.finalURL.value.toString()}")
//
//                    adapter.notifyDataSetChanged()
//                }
            } else {
                Log.d(TAG, "setOnCloseListener: called")
                adapter.differ.submitList(null)
                searchItemList.clear()
                noInternetConnectionLayout()
            }
            false
        }

I tried some methods in this question like adapter.notifyDataSetChanged() after submitting null but not working either

The result


Solution

  • Try this

    searchItemList.clear()
    
    linearLayoutManager?.removeAllViews()
    binding.accessoryRecyclerView.removeAllViews()
    adapter.differ.submitList(null)
    
    postViewModel.finalURL.value =
                        BASE_URL_POSTS_BY_LABEL + "posts?labels=Accessory&key=$API_KEY"
    requestApiData()