J'ai une mise en page composée d'un Parent RecyclerView avec un sous Recyclage à l'intérieur
je sais qu'il n'est pas bon de mettre une liste dans une autre liste, mais je dois utiliser les fonctionnalités de sous-liste telles que le balayage et le glisser-déposer.
Mon problème est que l’enfant Recyclerview prend le focus et empêche le parent de faire défiler si le point de contact était dessus. était horizontal ou en un clic, puis l’élément de la liste Recyclerview enfant glisse à gauche et à droite. Toute aide pour y parvenir?
J'ai finalement trouvé une solution.
Créer un LinearLayoutManager personnalisé
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
// it will always pass false to RecyclerView when calling "canScrollVertically()" method.
@Override
public boolean canScrollVertically() {
return false;
}
}
Puis instancier comme ceci pour le défilement vertical
CustomLinearLayoutManager customLayoutManager = new CustomLinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL,false);
Définissez enfin la disposition personnalisée en tant que gestionnaire de disposition de la vue recycleur
recyclerView.setLayoutManager(customLayoutManager);
Il peut ne pas être judicieux d’avoir des vues de recycleur incorporées, mais il est parfois impossible de l’éviter. Quelque chose comme ça pourrait marcher:
public class NoScrollRecycler extends RecyclerView {
public NoScrollRecycler(Context context){
super(context);
}
public NoScrollRecycler(Context context, AttributeSet attrs){
super(context, attrs);
}
public NoScrollRecycler(Context context, AttributeSet attrs, int style){
super(context, attrs, style);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev){
//Ignore scroll events.
if(ev.getAction() == MotionEvent.ACTION_MOVE)
return true;
//Dispatch event for non-scroll actions, namely clicks!
return super.dispatchTouchEvent(ev);
}
}
Cela désactivera l'événement de défilement, mais pas les événements de clic. Utilisez cette classe pour le "enfant" RecyclerView. Vous voulez que la vue de recyclage PARENT défile, mais pas l'enfant. Cela devrait suffire, car le parent sera simplement le RecyclerView standard, mais l’enfant sera celui personnalisé sans défilement, mais il gérera les clics. Peut-être faut-il désactiver les clics pour RecyclerView, le parent.
En outre, pour utiliser ceci en XML (si vous ne le saviez pas), procédez comme suit:
<com.yourpackage.location.NoScrollRecycler
...
... >
...
...
</com.yourpackage.location.NoScrollRecycler>
Dans votre nom d'activité.Java, dans la méthode onCreate (), écrivez:
RecyclerView v = (RecyclerView) findViewById(R.id.your_recycler_view_id);
v.setNestedScrollingEnabled(false);
De toute façon, si vous utilisez la mise en page de coordinateur, au cas où vous voulez simplifier les choses et que vous voulez désactiver le défilement imbriqué.
<Android.support.v4.widget.NestedScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/activitiesListRV"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"/>
</Android.support.v4.widget.NestedScrollView>
Et encore une fois, vous appliquez le même principe: Sur votre ActivityName.Java, dans la méthode onCreate (), écrivez:
RecyclerView v = (RecyclerView) findViewById(R.id.your_recycler_view_id);
v.setNestedScrollingEnabled(false);
Donc, fondamentalement, en XML, vous devez spécifier l'application: layout_behavior
app:layout_behavior="@string/appbar_scrolling_view_behavior">
Android:nestedScrollingEnabled="false"
dans l'enfant RecyclerView
Vous pouvez ajouter
Android:nestedScrollingEnabled="false"
à votre RecyclerView en XML ou
childRecyclerView.setNestedScrollingEnabled(false);
sur votre RecyclerView en Java.
MODIFIER:-
childRecyclerView.setNestedScrollingEnabled(false);
fonctionnera uniquement dans Android_version> 21 appareils. pour travailler dans tous les appareils, utilisez ce qui suit
ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);
vous pouvez utiliser setNestedScrollingEnabled(false);
sur sub RecyclerView
qui arrête le défilement dans sub RecyclerView
.
Dans mon cas, le code était
mInnerRecyclerView.setNestedScrollingEnabled(false);
où mInnerRecyclerView
étant intérieure RecyclerView
.
J'ai essayé plusieurs solutions suggérées et je n'ai pas pu en trouver une qui fonctionne dans mon cas. J'ai plus d'un RecyclerView dans un ScrollView utilisant un GridLayoutManager. Le résultat de la suggestion ci-dessus a entraîné l'arrêt du défilement de ScrollView chaque fois que je levais mon doigt (il ne glissait pas vers le haut ou le bas de la vue lorsque mon doigt était levé sur un RecyclerView)
En parcourant la source RecyclerView, onTouchEvent appelle dans le gestionnaire de mise en page:
final boolean canScrollHorizontally = mLayout.canScrollHorizontally();
final boolean canScrollVertically = mLayout.canScrollVertically();
Si vous les remplacez dans un gestionnaire de disposition personnalisé, renvoyez false et le défilement sera arrêté. Cela corrige également le problème où ScrollView cesserait de défiler brusquement.
Je pense que je suis trop en retard, mais ici, j'ai trouvé la solution si ça agace toujours quelqu'un:
RecyclerView v = (RecyclerView);
findViewById(R.id.your_recycler_view_id);
v.setNestedScrollingEnabled(false);
sensorsRecyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
Si vous ne souhaitez pas créer une vue personnalisée, vous pouvez également créer une présentation de même taille devant le RecyclerView et la rendre cliquable.
EDIT: Mais malheureusement, il bloque également les événements pour les éléments de la liste.