#kotlin #adapter #searchview
#kotlin #адаптер #searchview
Вопрос:
У меня проблема с этим кодом. После добавления кода для SearchView каждый раз, когда я нажимаю на один элемент, переходящий в StoreActivity, при возврате я получаю сообщение об ошибке
kotlin.Исключение UninitializedPropertyAccessException: адаптер свойств lateinit не был инициализирован
в строке
adapter.filter.фильтр(новый текст)
Как я могу устранить эту ошибку? Я не понимаю…
class HomeFragment : BaseFragment() {
private lateinit var adapter: MyStoreRecyclerViewAdapter
private var stores: List<StoreRealm> = ArrayList()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onResume() {
super.onResume()
setHasOptionsMenu(true)
if (isAdded) {
val systemService = this.context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
BLocationManager(this.context).getLocation {
loadHome()
if (!systemService.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
showEnableGpsDialog()
} else {
gpsWarning.visibility = View.GONE
}
}
}
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
inflater?.inflate(R.menu.search_store, menu)
val search: MenuItem = menu!!.findItem(R.id.searchStore)
val searchView: SearchView = search.actionView as SearchView
search(searchView)
searchView.maxWidth = Int.MAX_VALUE
super.onCreateOptionsMenu(menu, inflater)
}
private fun loadHome() {
loading_spinner?.visibility = View.VISIBLE
StoreService.getStores(
AuthManager.getMe()?.id!!, 0, BLocationManager.lat, BLocationManager.lon
) { response ->
loading_spinner?.visibility = View.GONE
if (response.getResult() != null amp;amp; response.getResult()?.isNotEmpty()!!) {
no_data_view?.visibility = View.GONE
store_view?.visibility = View.VISIBLE
stores = response.getResult()!!
// set up the RecyclerView
val recyclerView = view.store_recycler
recyclerView.layoutManager = GridLayoutManager(this.context, 1)
adapter = MyStoreRecyclerViewAdapter(stores) {
val intent = Intent(this.context, StoreActivity::class.java)
intent.putExtra("store_id", it.id)
startActivity(intent)
}
recyclerView.adapter = adapter
} else {
no_data_view?.visibility = View.VISIBLE
store_view?.visibility = View.GONE
}
if ((response.getError() as? UnknownHostException) != null) {
AuthManager.logout(this.activity)
NavigationManager.goToLogin(this.activity)
}
}
}
private fun search(searchView: SearchView) {
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
adapter.filter.filter(newText)
return true
}
})
}
}
Ответ №1:
Эта ошибка означает, что вы используете адаптер до его инициализации. Здесь это, вероятно, потому, что обратный вызов вашего хранилища является асинхронным.
Один из способов исправить эту проблему — поместить MutableList
в свой адаптер и инициализировать его onCreate пустым списком:
private lateinit var adapter: MyStoreRecyclerViewAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
adapter = MyStoreRecyclerViewAdapter(mutableListOf())
recyclerView.adapter = adapter
}
Затем, когда вызывается обратный вызов ваших хранилищ:
adapter.list = stores
Кроме того, не забудьте вызвать notifyDataSetChanged()
на adapter
после настройки списка, иначе ваши изменения не будут видны
Комментарии:
1. Я не понимаю, где вызвать notifyDataSetChanged().
2. Напишите после обновления списка вашего адаптера: ///// адаптер. list = stores ; adapter.notifyDataSetChanged() ///// Это указывает RecyclerView повторно отобразить все элементы в адаптере
3. Это работает, но когда я нажимаю на элемент, а затем возвращаюсь назад, текст поиска остается. Это можно удалить?
4. Извините, я не уверен, что вы имеете в виду, не могли бы вы быть немного конкретнее? Если вы пытаетесь очистить и
EditText
, вы можете просто вызватьyourEditText.text = ""
непосредственно передstartActivity
Ответ №2:
И, если вы не хотите mutableList
, просто инициализируйте свой ArrayList<>
private lateinit var arrayList: ArrayList<String>
поскольку
bluetoothDevices = arrayListOf()
в onCreate()
методе, прежде чем вы присоедините его к своему Adapter