Отображение предыдущего списка в RecyclerView при закрытии SearchView - PullRequest
0 голосов
/ 26 мая 2020

Я создаю приложение, которое позволяет пользователю искать местоположение. Используя SearchView, приложение выполняет вызов API и показывает результат в RecyclerView. Когда пользователь впервые загружает приложение, оно показывает историю поиска, которую можно фильтровать. Моя проблема в том, что когда я вызываю api и закрываю SearchView, я вижу предыдущую историю местоположений плюс результаты вызова api в нижней части RecyclerView. Как мне обновить sh результаты, чтобы увидеть новую историю поиска только при закрытии SearchView?

Это моя активность:

class MainActivity : AppCompatActivity(), SearchView.OnQueryTextListener, SearchView.OnCloseListener {

    @Inject
    lateinit var mainViewModelFactory: MainViewModelFactory
    private lateinit var mainViewModel: MainViewModel

    private lateinit var searchView: SearchView

    private val adapter = LocationListAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)

        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.searchHistoryRecyclerView.adapter = adapter
        binding.searchHistoryRecyclerView.layoutManager = LinearLayoutManager(this)


        mainViewModel = ViewModelProvider(this, mainViewModelFactory).get(MainViewModel::class.java)


        mainViewModel.searchHistory.observe(this, Observer { locationList ->
            locationList?.let {
                adapter.loadLocations(locationList.toMutableList())
            }
        })

        mainViewModel.searchResults.observe(this, Observer { locationList ->
            locationList?.let {
                adapter.loadLocations(locationList.toMutableList())
            }
        })
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)

        val searchItem = menu?.findItem(R.id.action_search)
        if (searchItem != null) {
            searchView = searchItem.actionView as SearchView

            searchView.queryHint = "Search for a location"
            searchView.setOnQueryTextListener(this)

        }
        return super.onCreateOptionsMenu(menu)
    }

    override fun onQueryTextSubmit(query: String?): Boolean {
        if(!query.isNullOrEmpty()) performSearch(query)
        return false
    }

    override fun onQueryTextChange(newText: String?): Boolean {
        adapter.filter.filter(newText)
        return false
    }

    private fun performSearch(query: String) {
        mainViewModel.setCity(query)
    }

    override fun onClose(): Boolean {
        adapter.filter.filter("")
        return false
    }
}

Модель представления:

class MainViewModel @Inject constructor(private val weatherRepository: WeatherRepository) : ViewModel() {

    val searchHistory: LiveData<List<Location>> = liveData(Dispatchers.IO) {
       emit(weatherRepository.getSearchHistory())
    }

    private val city = MutableLiveData<String>()

    val searchResults: LiveData<List<Location>> = city.switchMap {
        liveData(Dispatchers.IO) {
            emit(weatherRepository.getLocationsFromApi(it))
            weatherRepository.save(Location(name = it, countryCode = it))
        }
    }

    fun setCity(newCity: String) {
        city.value = newCity
    }
}

И адаптер:

class LocationListAdapter : RecyclerView.Adapter<LocationListAdapter.ViewHolder>(), Filterable {

    private var locations = mutableListOf<Location>()
    private var locationListFull = mutableListOf<Location>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_item, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(locations[position])
    }

    override fun getItemCount(): Int =locations.size

    fun loadLocations(list: MutableList<Location>) {
        locations = list
        locationListFull.addAll(locations)
        notifyDataSetChanged()
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        fun bind(item: Location) {
            itemView.locationTextView.text = item.name
        }
    }

    override fun getFilter(): Filter {
        return simpleSearchFilter
    }

    private val simpleSearchFilter: Filter = object : Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults {
            val filteredList: MutableList<Location> = mutableListOf()

            if (constraint.isNullOrEmpty()) {
                filteredList.addAll(locationListFull)
            } else {
                val filterPattern = constraint.toString().toLowerCase()

                for (item in locationListFull) {
                    if (item.name.toLowerCase().contains(filterPattern)) {
                        filteredList.add(item)
                    }
                }
            }
            val results = FilterResults()
            results.values = filteredList
            return results
        }

        @Suppress("UNCHECKED_CAST")
        override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
            locations.clear()
            locations.addAll(results?.values as MutableList<Location>)
            notifyDataSetChanged()
        }
    }
}
...