Не обновляется список RecyclerView после добавления объекта в базу данных
В фрагменте я делаю запрос на добавление города в базу данных, он успешно добавляется, я проверил базу после нажатия кнопки, там плюс 1 объект. Далее вызываю метод getAll() чтобы обновить слушатель liveData,и подписываюсь на изменения в своем фрагменте. Далее в адаптеру передаю новый список и в сеттере вызываю notifyDataSetChanged(). Обновления списка срабатывает только при перезапуске фрагмента. Метод удаления из списка срабатывает, но не всегда с первого раза.
class MainViewModel : ViewModel() {
private val database = App.instance.getDatabase()
private val fiveDaysWeather = MutableLiveData<String>()
private val allCities = MutableLiveData<List<City>>()
fun getAllCities(): LiveData<List<City>> = allCities
fun getWeather(): MutableLiveData<String> = fiveDaysWeather
fun getAll() {
viewModelScope.launch(Dispatchers.IO) {
val citiesDB = database.cityDao().getAll()
allCities.postValue(citiesDB)
}
}
fun insert(city: City) {
viewModelScope.launch(Dispatchers.IO) {
val existingCity = database.cityDao().getCityByName(city.name)
if (existingCity == null) {
database.cityDao().insert(city)
getAll()
} else {
city.uid = existingCity.uid
database.cityDao().update(city)
}
}
}
class CitiesAdapter(private val cityActionListener: CityActionListener) :
RecyclerView.Adapter<CitiesAdapter.CitiesViewHolder>(), View.OnClickListener {
class CitiesViewHolder(val binding: ItemCityBinding) : RecyclerView.ViewHolder(binding.root)
override fun onClick(v: View) {
val city = v.tag as City
when (v.id) {
R.id.deleteCityButton -> {
cityActionListener.onCityDelete(city)
}
else -> {
cityActionListener.onCityDetails(city)
}
}
}
var cities: List<City> = listOf()
set(newValue) {
field = newValue
notifyDataSetChanged()
}
override fun getItemCount(): Int = cities.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CitiesViewHolder {
val inflater = LayoutInflater.from(parent.context)
val binding = ItemCityBinding.inflate(inflater, parent, false)
binding.root.setOnClickListener(this)
binding.deleteCityButton.setOnClickListener(this)
return CitiesViewHolder(binding)
}
override fun onBindViewHolder(holder: CitiesViewHolder, position: Int) {
val city = cities[position]
with(holder.binding) {
holder.itemView.tag = city
deleteCityButton.tag = city
nameTextView.text = city.name
temperatureTextView.text = city.weatherList[0].temperature
precipitationTextView.text = city.weatherList[0].precipitation
windSpeedTextView.text = city.weatherList[0].wind_speed
imageViewMainDescription.setImageResource(city.weatherList[0].image)
}
}
}
class CitiesFragment : Fragment() {
private lateinit var adapter: CitiesAdapter
private lateinit var viewModel: MainViewModel
private lateinit var onDataPass: OnDataPass
private var _binding: FragmentCitiesBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
viewModel = ViewModelProvider(this)[MainViewModel::class.java]
_binding = FragmentCitiesBinding.inflate(inflater, container, false)
adapter = CitiesAdapter(object : CityActionListener{
/**Метод удаления и обновления списка*/
override fun onCityDelete(city: City) {
viewModel.delete(city)
viewModel.getAll()
adapter.notifyDataSetChanged()
}
override fun onCityDetails(city: City) {
onDataPass.updateUICity(city)
activity?.supportFragmentManager?.popBackStack()
}
})
val layoutManager = LinearLayoutManager(activity)
binding.recyclerviewFragment.layoutManager = layoutManager
binding.recyclerviewFragment.adapter = adapter
return binding.root
}
override fun onAttach(context: Context) {
super.onAttach(context)
onDataPass = context as OnDataPass
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.getAllCities().observe(viewLifecycleOwner, Observer {
adapter.cities = it
})
viewModel.getAll()
binding.writeCityEditTextFragment.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
return@setOnEditorActionListener findCity()
}
return@setOnEditorActionListener false
}
}
private fun findCity(): Boolean {
return if (binding.writeCityEditTextFragment.text.toString() == "") {
Toast.makeText(App.instance, "Введите город для поиска!", Toast.LENGTH_SHORT).show()
true
} else {
binding.writeCityEditTextFragment.hideKeyboard()
val cityName = binding.writeCityEditTextFragment.text.toString().trim()
onDataPass.findNewCity(cityName)
false
}
}
private fun View.hideKeyboard() {
val inputManager =
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputManager.hideSoftInputFromWindow(windowToken, 0)
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}