web-dev-qa-db-fra.com

Comment supprimer un élément de PagedListAdapter dans Android Composant de pagination

J'ai utilisé la pagination avec Retrofit pour charger la liste des données de notifications de REST API.

Lorsque j'appuie sur le bouton Supprimer d'un élément de notification, j'appelle l'API Supprimer pour le supprimer. Quelle est la bonne façon de le supprimer de PagedListAdapter après la suppression de la réponse de l'API? PagedList ou PagedListAdapter ne prend pas en charge la suppression de l'élément par index ou objet.

J'ai essayé d'appeler DataSource.validate() mais il se recharge depuis le début, pas depuis la page actuelle.

13
phamxuanlu

Selon le doc officiel :

Si vous avez des signaux de mise à jour plus granulaires, comme une API réseau signalant une mise à jour à un seul élément de la liste, il est recommandé de charger les données du réseau dans la mémoire. Présentez ensuite ces données à la PagedList via un DataSource qui encapsule un instantané en mémoire. Chaque fois que la copie en mémoire change, invalidez la DataSource précédente et une nouvelle enveloppant le nouvel état de l'instantané peut être créée.

PagedList est immuable, vous ne pouvez donc pas y apporter de modifications. Ce que vous devez faire, c'est:

  1. maintenir une liste modifiable L stockant les réponses de votre serveur dans votre DataSource personnalisé.
  2. passez-le à LoadInitialCallback.onResult() (le PagedList est soutenu par L maintenant).
  3. faites ce que vous voulez pour L.
  4. appelez DataSource.invalidate() pour l'appairer avec une nouvelle source de données, afin que DataSource.loadInitial() soit appelé pour refléter les modifications de l'étape 3.
5
jaychang0917

Pas la solution la plus élégante, mais elle fonctionne. Par exemple, il est préférable d'utiliser cette approche lors de l'utilisation de la pagination Firestore lors de la suppression d'un élément au lieu de récupérer la liste entière ....

Il peut également être optimisé, car il ne s'agit que d'un brouillon. L'idée principale est d'utiliser le factice ViewHolder avec une vue vierge.

class PostAdapter(
    options: FirestorePagingOptions<Post>,
    private val feedViewModel: FeedViewModel
) : FirestorePagingAdapter<Post, RecyclerView.ViewHolder>(options) {

    companion object {
        private const val DELETED_VIEW_TYPE = 1
        private const val NORMAL_VIEW_TYPE = 2
    }

    private val deletedItems = arrayListOf<String>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val inflater = parent.getLayoutInflater()
        return when (viewType) {
            NORMAL_VIEW_TYPE -> {
                PostViewHolder(ItemPostBinding.inflate(inflater, parent, false))
            }
            else -> BindingViewHolder<ItemDeletedPostBinding>(
                ItemDeletedPostBinding.inflate(inflater, parent, false)
            )
        }

    }

    override fun getItemViewType(position: Int): Int {
        val item = getItem(position)?.toObject(Post::class.Java)
        if (deletedItems.firstOrNull { it == item?.postId }.isNotNull()) {
            return DELETED_VIEW_TYPE
        } else {
            return NORMAL_VIEW_TYPE
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, model: Post) {
        if (holder is PostViewHolder) {
            holder.bind(model, feedViewModel)
        }
    }

    fun deleteItem(post: Post) {
        val postId = post.postId

        if (postId != null) {
            val element = currentList?.find { it.toObject(Post::class.Java)?.postId == postId }
            val index = currentList?.indexOf(element)

            index?.let {
                deletedItems.add(postId)
                notifyItemChanged(it)
            }
        }
    }
}

0
Antonis Radz