Je souhaite modifier mon ListView dont je dispose actuellement pour utiliser RecyclerView
afin de pouvoir utiliser StaggeredGridLayoutManager
mais RecyclerView n'a pas la possibilité d'ajouter un en-tête comme ListView.
Habituellement, avec un ListView, je place une vue vide dans l'en-tête, place l'image en dessous de la vue en liste et traduit l'image en bas en faisant défiler la liste pour créer l'effet Parallax
.
Donc, sans en-tête, comment puis-je créer le même effet de parallaxe avec RecyclerView
?
Donc, aujourd’hui, j’ai essayé d’archiver cet effet sur une RecyclerView
. Je pouvais le faire, mais comme le code est trop important, je vais coller ici mon projet github et expliquer quelques points clés du projet.
https://github.com/kanytu/Android-parallax-recyclerview
Nous devons d’abord examiner getItemViewType
dans la classe RecyclerView.Adapter
. Cette méthode définit le type de vue dont nous traitons. Ce type sera transmis à onCreateViewHolder
et nous pouvons y gonfler différentes vues. Donc ce que j'ai fait était: vérifiez si la position est la première. Si c'est le cas, gonflez l'en-tête, sinon gonflez une ligne normale.
J'ai également ajouté une variable CustomRelativeLayout
qui coupe la vue afin que nous n'ayons aucun problème avec les séparateurs et les rangées situées au-dessus de l'en-tête.
À partir de ce moment, vous semblez connaître le reste de la logique sous-jacente.
Le résultat final était:
MODIFIER:
Si vous devez insérer quelque chose dans l'adaptateur, assurez-vous d'indiquer la position correcte en ajoutant 1 dans la méthode notifyItemChanged/Inserted
. Par exemple:
public void addItem(String item, int position) {
mData.add(position, item);
notifyItemInserted(position + 1); //we have to add 1 to the notification position since we don't want to mess with the header
}
Une autre modification importante que j'ai faite est la logique de défilement. Le système mCurrentOffset
que j'utilisais ne fonctionnait pas avec l'insertion d'élément, car le décalage changerait si vous ajoutez un élément. Alors ce que j'ai fait était:
ViewHolder holder = findViewHolderForPosition(0);
if (holder != null)
((ParallaxRecyclerAdapter) getAdapter()).translateHeader(-holder.itemView.getTop() * 0.5f);
Pour tester cela, j'ai ajouté une postDelayed
Runnable, démarré l'application, fait défiler l'écran à la fin, ajouté l'élément en position 0 et fais défiler à nouveau. Le résultat était:
Si quelqu'un recherche d'autres effets de parallaxe, il peut consulter mon autre dépôt:
la façon la plus simple de le faire est d'utiliser ci-dessous onScrollListener
sans faire appel à aucune bibliothèque.
View view = recyclerView.getChildAt(0);
if(view != null && recyclerView.getChildAdapterPosition(view) == 0) {
view.setTranslationY(-view.getTop() / 2);// or use view.animate().translateY();
}
assurez-vous que votre deuxième élément viewHolder
a une couleur d'arrière-plan qui correspond à l'arrière-plan du tiroir/de l'activité. si le défilement ressemble à la parallaxe.
Pour kotlin, vous pouvez configurer la vue recycleur comme ci-dessous
//setting parallax effects
recyclerView.addOnScrollListener(object :RecyclerView.OnScrollListener(){
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val view = recyclerView?.getChildAt(0)
if (view != null && recyclerView?.getChildAdapterPosition(view) === 0) {
val imageView = view.findViewById(R.id.parallaxImage)
imageView.translationY = -view.top / 2f
}
}
})
Cette réponse est destinée à ceux qui sont curieux d’ajouter un en-tête de parallaxe à un GridLayoutManager
ou un StaggeredGridLayoutManager
Vous voudrez ajouter le code suivant à votre adaptateur dans onBindViewHolder
ou onCreateViewHolder
StaggeredGridLayoutManager.LayoutParams layoutParams =
(StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
layoutParams.setFullSpan(true);