Skip to content

Instantly share code, notes, and snippets.

View VictorAlbertos's full-sized avatar

Víctor Albertos VictorAlbertos

View GitHub Profile
class SampleFragment : Fragment(R.layout.sample_fragment) {
private val viewModel: SampleViewModel by viewModels()
private val sampleAdapter by lazy { SampleAdapter(viewModel) }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val rvItems = view.findViewById<RecyclerView>(R.id.rvItems)
rvItems.layoutManager = LinearLayoutManager(context)
class SampleAdapter(private val sampleViewModel: SampleViewModel) :
PagingDataAdapter<SampleEntity, SampleAdapter.ViewHolder>(Comparator) {
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val sampleEntity = getItem(position) ?: return
holder.itemView.findViewById<TextView>(R.id.tvItem).text = sampleEntity.name
holder.itemView.findViewById<View>(R.id.ivRemove).setOnClickListener {
sampleViewModel.onViewEvent(SampleViewEvents.Remove(sampleEntity))
}
holder.itemView.findViewById<View>(R.id.ivEdit).setOnClickListener {
fun onViewEvent(sampleViewEvents: SampleViewEvents) {
modificationEvents.value += sampleViewEvents
}
private fun applyEvents(paging: PagingData<SampleEntity>, sampleViewEvents: SampleViewEvents): PagingData<SampleEntity> {
return when (sampleViewEvents) {
is SampleViewEvents.Remove -> {
paging
.filter { sampleViewEvents.sampleEntity.id != it.id }
}
class SampleViewModel : ViewModel() {
private val modificationEvents = MutableStateFlow<List<SampleViewEvents>>(emptyList())
// combine them with the data coming from paging
private val combined =
Pager(PagingConfig(pageSize = SampleRepository.PAGE_SIZE)) { SamplePagingSource(SampleRepository()) }.flow
.cachedIn(viewModelScope)
.combine(modificationEvents) { pagingData, modifications ->
modifications.fold(pagingData) { acc, event ->
applyEvents(acc, event)
class SamplePagingSource(
private val sampleRepository: SampleRepository
) : PagingSource<Int, SampleEntity>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, SampleEntity> {
return try {
val data = sampleRepository.getNextPage(lastSeenId = params.key ?: 1)
.map { SampleEntity(it, "Page number: $it") }
LoadResult.Page(
data = data,
class SampleRepository {
suspend fun getNextPage(lastSeenId: Int): List<Int> {
return withContext(Dispatchers.IO) {
(lastSeenId..lastSeenId + PAGE_SIZE).map { it }
}
}
companion object {
const val PAGE_SIZE = 20
}
sealed class SampleViewEvents {
data class Edit(val sampleEntity: SampleEntity) : SampleViewEvents()
data class Remove(val sampleEntity: SampleEntity) : SampleViewEvents()
object InsertItemHeader : SampleViewEvents()
object InsertItemFooter : SampleViewEvents()
}
data class SampleEntity(val id: Int, val name: String)
//read from loader
api
.compose(rxCache.<User>.read("mock").toObservable())
.subscribe();
//read without loader
RxCache.<User>.read("mock")
.toObservable()
.subscribe();