Снимок экрана приложения
Я хочу иметь возможность нажимать кнопку сердечка на любом элементе Pokemon и обновлять поле «isFavorite» в для модели SimplePokemon значение true или false. Насколько я понимаю, если бы я хотел изменить один элемент из этого PagedList, мне нужно было бы сделать недействительным источник данных, и это теоретически должно сгенерировать новые LiveData PagedList, которые можно было бы передать в адаптер и отобразить на экране.
Вопрос: Как я могу обновить один элемент из PagedList с помощью библиотеки подкачки без необходимости использования Room или какой-либо другой базы данных?
В будущем я хочу масштабировать это решение для ленты социальных сетей, где пользователи смогут ставить лайки публикациям, но я не знаю, целесообразно ли хранить элементы ленты социальных сетей в базе данных, такой как Room. необходимо (или эффективно), поскольку эти элементы корма постоянно меняются. Поэтому я решил хранить их в ViewModel, а затем очищать каждый раз, когда пользователь выходит из приложения.
Вот мой код:
SimplePokemon.kt:
Код: Выделить всё
data class SimplePokemon(
@SerializedName("name") val name: String,
@SerializedName("url") val url: String,
var isFavorite: Boolean = false
)
Код: Выделить всё
class PokemonViewModel(application: Application) : AndroidViewModel(application) {
private val config = PagedList.Config.Builder()
.setPageSize(20)
.setEnablePlaceholders(false)
.build()
private fun initializedPagedListBuilder(config: PagedList.Config): LivePagedListBuilder {
val dataSourceFactory = object : DataSource.Factory() {
override fun create(): DataSource {
return PokemonDataSource()
}
}
return LivePagedListBuilder(dataSourceFactory, config)
}
fun pokemonPagedListLiveData(): LiveData
> {
return initializedPagedListBuilder(config).build()
}
}
Код: Выделить всё
class PokemonAdapter :
PagedListAdapter(PokemonDiffUtil()) {
inner class PokemonViewHolder(v: View) : RecyclerView.ViewHolder(v) {
private val pokemonNameTextView: TextView = v.findViewById(R.id.pokemon_name_text_view)
private val pokemonFavoriteToggle: ToggleButton =
v.findViewById(R.id.pokemon_favorite_toggle_button)
fun bind(data: SimplePokemon) {
pokemonNameTextView.text = data.name
pokemonFavoriteToggle.isChecked = data.isFavorite
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PokemonViewHolder {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.item_simple_pokemon, parent, false)
return PokemonViewHolder(view)
}
override fun onBindViewHolder(holder: PokemonViewHolder, position: Int) {
val item = getItem(position)
item?.let { holder.bind(it) }
}
}
Код: Выделить всё
class PokemonDataSource : PageKeyedDataSource() {
private val api = NetworkService.pokemonNetworkInterface
override fun loadInitial(
params: LoadInitialParams,
callback: LoadInitialCallback
) {
api.getPokemon().enqueue(object : Callback
>> {
override fun onFailure(call: Call?, t: Throwable?) {
Log.e("PokemonDataSource", "Failed to fetch data!")
}
override fun onResponse(
call: Call?,
response: Response
) {
val listing = response.body()
val pokemon = listing?.results
callback.onResult(pokemon ?: listOf(), listing?.previous, listing?.next)
}
})
}
override fun loadAfter(
params: LoadParams,
callback: LoadCallback
) {
api.getPokemon(url = params.key)
.enqueue(object : Callback {
override fun onFailure(
call: Call?,
t: Throwable?
) {
Log.e("PokemonDataSource", "Failed to fetch data! Oh Noooo!")
}
override fun onResponse(
call: Call?,
response: Response
) {
val listing = response.body()
val pokemon = listing?.results
callback.onResult(pokemon ?: listOf(), listing?.next)
}
})
}
override fun loadBefore(
params: LoadParams,
callback: LoadCallback
) {
api.getPokemon(url = params.key)
.enqueue(object : Callback {
override fun onFailure(
call: Call?,
t: Throwable?
) {
Log.e("PokemonDataSource", "Failed to fetch data! Oh Noooo!")
}
override fun onResponse(
call: Call?,
response: Response
) {
val listing = response.body()
val pokemon = listing?.results
callback.onResult(pokemon ?: listOf(), listing?.previous)
}
})
}
Идеальным сценарием было бы хранить список покемонов до тех пор, пока активно действие, и иметь возможность локально обновлять отдельные элементы покемонов. Теоретически я бы также отправил POST-запрос на серверную часть для обновления покемонов на серверной стороне, но я просто пытаюсь упростить вопрос.
Любой помощь будет искренне признательна.
Подробнее здесь: https://stackoverflow.com/questions/602 ... ng-library