#android #kotlin #android-recyclerview #android-search #android-bottomsheetdialog
Вопрос:
У меня неловкая ситуация, в которой я два дня пытался найти причину и исправить ее, и у меня ничего не вышло.
Позвольте мне сначала все объяснить.
При запуске приложения recyclerView
в «домашнем фрагменте» заполняются данные, которые были получены из Firestore
. У меня есть строка поиска на панели инструментов вверху, и когда я что-то набираю, она сужает список элементов в списке recyclerView
. У меня есть a FloatingActionButton
, который выведет a BottomSheetDialogFragment
, содержащий категории товаров. Когда я выбираю категорию из нее, recyclerView
в «Домашнем фрагменте» заполняется на основе выбранной категории. До сих пор нет никаких проблем.
Если я выполню поиск после выбора категории, он без каких-либо проблем сузит список товаров. Когда я выбираю «Домашнюю часть» из bottomNavigation
, после выбора категории из BottomSheetDialogFragment
, результат поиска не отображается. Однако, если я выберу «Домашняя страница» из bottomNavigation
пункта после выбора любого другого пункта нижнего меню, но не перейду в раздел BottomSheetDialogFragment
и не выберу категорию, то с поиском проблем не возникнет. Это происходит только тогда, когда я выбираю категорию, а затем возвращаюсь к «Домашнему фрагменту», нажав на нижнее меню. Может ли кто-нибудь помочь мне найти и устранить проблему?
Ниже приведено то, что у меня есть в «Домашнем фрагменте» для поиска.
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { menu.clear() // THIS LINE OF CODE IS ADDED SO THAT WHEN WE SELECT A CATEGORY FROM THE BOTTOMSHEET THE MENU ITEMS WON'T DUPLICATE inflater.inflate(R.menu.home_menu, menu) super.onCreateOptionsMenu(menu, inflater) val item = menu.findItem(R.id.my_search_bar) val searchView = item?.actionView as SearchView searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String?): Boolean { srchTempProductsList.clear() if (query != null) { if (query.isNotEmpty()) { srchProductsList.forEach { if (it.label.toLowerCase(Locale.getDefault()).contains(query)) { srchTempProductsList.add(it) } binding.rvHomeItems.adapter?.notifyDataSetChanged() } if (srchTempProductsList.size == 0) { showCustomAlertDialog() } } else { srchTempProductsList.clear() srchTempProductsList.addAll(srchProductsList) binding.rvHomeItems.adapter?.notifyDataSetChanged() } } return false } override fun onQueryTextChange(newText: String?): Boolean { srchTempProductsList.clear() val searchText = newText!!.toLowerCase(Locale.getDefault()) if (searchText.isNotEmpty()) { srchProductsList.forEach { if (it.label.toLowerCase(Locale.getDefault()).contains(searchText)) { srchTempProductsList.add(it) } binding.rvHomeItems.adapter?.notifyDataSetChanged() } if (srchTempProductsList.size == 0) { showCustomAlertDialog() } } else { srchTempProductsList.clear() srchTempProductsList.addAll(srchProductsList) binding.rvHomeItems.adapter?.notifyDataSetChanged() } return false } }) }
I have the following in the ‘BottomSheetDialogFragment’ to pass the category to the ‘HomeFragment’
categoryAdapter.setOnClickListener(object :HomeCategoryListAdapter.OnClickListener{ override fun onClick(position: Int, category: Categories) { val myFragment = HomeFragment() val bundle = Bundle() bundle.putString("category", category.category) myFragment.arguments = bundle fragmentManager?.beginTransaction()?.replace(R.id.nav_host_fragment,myFragment)?.commit() dismiss() } })
and the following in the onCreateView
of ‘HomeFragment’
val bundle = this.arguments if (bundle!=null) { if (bundle.getString("category")!="All Products"){ filterCategory = bundle.getString("category") }else{ filterCategory =null } }
и вот как я получаю список продуктов в «Домашнем фрагменте»
fun getProductList() { srchProductsList.clear() srchTempProductsList.clear() if (filterCategory!=null){ mFireStore.collection("prods") .whereEqualTo("category",filterCategory) .get() .addOnCompleteListener { if (it.isSuccessful) { for (document in it.result) { val product = document.toObject(Product::class.java) product.product_id = document.id srchProductsList.add(product) } } else { } srchTempProductsList.addAll(srchProductsList) listProductBasedOnView() } .addOnFailureListener { Log.d("Known Error", "This ....") } }else{ mFireStore.collection("prods") .get() .addOnCompleteListener { if (it.isSuccessful) { for (document in it.result) { val product = document.toObject(Product::class.java) product.product_id = document.id srchProductsList.add(product) } } else { } srchTempProductsList.addAll(srchProductsList) listProductBasedOnView() } .addOnFailureListener { Log.d("Known Error", "This ...") } } }
Комментарии:
1. Насколько я понимаю ваш код, вы передаете «категорию» в качестве аргумента во фрагменте. Но если вы выберете категорию на нижней странице, а затем нажмете на нижнюю панель, чтобы изменить фрагмент, вы, по сути, не передадите там никаких аргументов. Вы должны попробовать это сделать и проверить.
2. Ну, при запуске приложения я хочу, чтобы все элементы отображались независимо от их категории. Следовательно, «Категория фильтра» имеет значение
null
какprivate var filterCategory: String?= null
. Кроме того, если кто-то выберет «Все товары» из категории, я не хочу фильтровать свой запрос, и поэтому я проверяюif (bundle!=null)
, и соответственно изменяется значение «Категория фильтра». Ты имел в виду что-то другое?3. Что ж, именно это я и имел в виду. Вы не сохраняете категорию, когда пользователь выбирает ее на нижнем листе, и, следовательно, всякий раз, когда вы переходите к главному фрагменту с помощью нижней навигации, вы не видите фильтра, примененного к вашему списку. Либо вам нужно сохранить выбранную категорию из нижнего листа в качестве статической переменной, либо, возможно, в ваших общих настройках, или, возможно, даже передать ее в виде пакета, и вам будет хорошо. Вы также можете открыть фрагмент «Главная страница», как только пользователь выберет категорию. (Это зависит от вашего выбора для потока приложения).
4. Можете ли вы проверить код, который у меня есть в фрагменте BottomSheetDialog, и сказать мне, правильно ли я делаю, чтобы передать его в виде пакета также в разделе
onCreate
«Домашняя страница», где я проверяю, какая категория возвращается в виде пакета из фрагмента BottomSheetDialog. Да, я хочу показать фрагмент, как только пользователь выберет категорию, и я сделал это,dismiss()
чтобы закрытьBottomSheetDialogFragment
ее .5.
R.id.nav_host_fragment
похоже, вы используете компоненты архитектуры с NavController в некоторых частях приложения? или вы выполняете все транзакции фрагментов вручную?