web-dev-qa-db-fra.com

Faites défiler RecyclerView pour afficher l'élément sélectionné en haut

Je cherche un moyen de faire défiler une RecyclerView pour afficher l'élément sélectionné en haut.

Dans une ListView, j'ai pu le faire en utilisant scrollTo(x,y) et en obtenant le sommet de l'élément à centrer.

Quelque chose comme:

@Override
public void onItemClick(View v, int pos){
    mylistView.scrollTo(0, v.getTop());
}

Le problème est que la variable RecyclerView renvoie une erreur lorsqu’elle utilise sa méthode scrollTo en disant 

RecyclerView ne prend pas en charge le défilement vers une position absolue

Comment puis-je faire défiler une RecyclerView pour placer l'élément sélectionné en haut de la vue?

169
Distwo

Si vous utilisez LinearLayoutManager ou StaggeredGridLayoutManager, ils ont chacun une méthode scrollToPositionWithOffset qui prend à la fois la position et le décalage du début de l’élément de RecyclerView, ce qui semble produire les résultats escomptés (régler le décalage sur 0 doit s’aligner sur le haut).

Par exemple:

//Scroll item 2 to 20 pixels from the top
linearLayoutManager.scrollToPositionWithOffset(2, 20);
317
Niraj

Si vous recherchez LinearLayout Manager vertical, vous pouvez obtenir un défilement régulier à l’aide d’une variable LinearSmoothScroller personnalisée:

import Android.content.Context;
import Android.graphics.PointF;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.LinearSmoothScroller;
import Android.support.v7.widget.RecyclerView;

public class SnappingLinearLayoutManager extends LinearLayoutManager {

    public SnappingLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                                       int position) {
        RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

    private class TopSnappedSmoothScroller extends LinearSmoothScroller {
        public TopSnappedSmoothScroller(Context context) {
            super(context);

        }

        @Override
        public PointF computeScrollVectorForPosition(int targetPosition) {
            return SnappingLinearLayoutManager.this
                    .computeScrollVectorForPosition(targetPosition);
        }

        @Override
        protected int getVerticalSnapPreference() {
            return SNAP_TO_START;
        }
    }
}

utilisez une instance du gestionnaire de mise en page dans la vue de recyclage, puis l'appel de recyclerView.smoothScrollToPosition(pos); facilitera le défilement jusqu'à la position sélectionnée en haut de la vue du recycleur.

76
nizammoidu

// élément de défilement pos

linearLayoutManager.scrollToPositionWithOffset(pos, 0);
41
HBQ

Il vous suffit d'appeler recyclerview.scrollToPosition(position). C'est très bien!

Si vous souhaitez l'appeler dans l'adaptateur, laissez simplement l'adaptateur avoir l'instance de recyclerview ou l'activité ou le fragment qui contient recyclerview, puis implémentez la méthode getRecyclerview() dans celles-ci.

J'espère que cela peut vous aider.

18
Zero

idem avec régulateur de vitesse

public class SmoothScrollLinearLayoutManager extends LinearLayoutManager {
private static final float MILLISECONDS_PER_INCH = 110f;
private Context mContext;

public SmoothScrollLinearLayoutManager(Context context,int orientation, boolean reverseLayout) {
    super(context,orientation,reverseLayout);
    mContext = context;
}

@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                                   int position) {
    RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext()){
        //This controls the direction in which smoothScroll looks for your view
        @Override
        public PointF computeScrollVectorForPosition(int targetPosition) {
            return new PointF(0, 1);
        }

        //This returns the milliseconds it takes to scroll one pixel.
        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
        }
    };
    smoothScroller.setTargetPosition(position);
    startSmoothScroll(smoothScroller);
}


private class TopSnappedSmoothScroller extends LinearSmoothScroller {
    public TopSnappedSmoothScroller(Context context) {
        super(context);

    }

    @Override
    public PointF computeScrollVectorForPosition(int targetPosition) {
        return SmoothScrollLinearLayoutManager.this
                .computeScrollVectorForPosition(targetPosition);
    }

    @Override
    protected int getVerticalSnapPreference() {
        return SNAP_TO_START;
    }
}
}
11
user2212515

ce que j'ai fait pour restaurer la position de défilement après l'actualisation du bouton RecyclerView sur un clic:

if (linearLayoutManager != null) {

    index = linearLayoutManager.findFirstVisibleItemPosition();
    View v = linearLayoutManager.getChildAt(0);
    top = (v == null) ? 0 : (v.getTop() - linearLayoutManager.getPaddingTop());
    Log.d("TAG", "visible position " + " " + index);
}

else{
    index = 0;
}

linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.scrollToPositionWithOffset(index, top);

obtenir le décalage du premier élément visible depuis le haut avant de créer l'objet linearLayoutManager et après l'instancier, le scrollToPositionWithOffset de l'objet LinearLayoutManager a été appelé.

6
tsiro

Essayez ce qui a fonctionné pour moi cool!

Créer une variable private static int displayedposition = 0;

Passons maintenant à la position de votre RecyclerView dans votre activité.

myRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                LinearLayoutManager llm = (LinearLayoutManager) myRecyclerView.getLayoutManager();


                displayedposition = llm.findFirstVisibleItemPosition();


            }
        });

Placez cette déclaration à l'endroit où vous souhaitez placer l'ancien site affiché dans votre vue.

LinearLayoutManager llm = (LinearLayoutManager) mRecyclerView.getLayoutManager();
        llm.scrollToPositionWithOffset(displayedposition , youList.size());

Eh bien ça y est, ça a bien fonctionné pour moi\o /

6
user3740244

faire défiler à une position particulière
et cela m'a beaucoup aidé . par écouteur de clic, vous pouvez obtenir la position dans votre adaptateur

layoutmanager.scrollToPosition(int position);
3
Sandeep Singh

Dans mon cas, ma RecyclerView a un rembourrage comme celui-ci 

<Android.support.v7.widget.RecyclerView
     ...
     Android:paddingTop="100dp"
     Android:clipToPadding="false"
/>

Ensuite, pour faire défiler un élément vers le haut, je dois

recyclerViewLinearLayoutManager.scrollToPositionWithOffset(position, -yourRecyclerView.getPaddingTop());
2
Linh

Je ne sais pas pourquoi je n'ai pas trouvé la meilleure réponse mais c'est vraiment simple.

recyclerView.smoothScrollToPosition(position);

Aucune erreur

Crée des animations

1
Lucem
If you want to scroll automatic without show scroll motion then you need to write following code:

**=> mRecyclerView.getLayoutManager().scrollToPosition(position);**

If you want to display scroll motion then you need to add following code.
=>Step 1: You need to declare SmoothScroller.

RecyclerView.SmoothScroller smoothScroller = new
                LinearSmoothScroller(this.getApplicationContext()) {
                    @Override
                    protected int getVerticalSnapPreference() {
                        return LinearSmoothScroller.SNAP_TO_START;
                    }
                };

=>step 2: You need to add this code any event you want to perform scroll to specific position.
=>First you need to set target position to SmoothScroller.

**smoothScroller.setTargetPosition(position);**

=>Then you need to set SmoothScroller to LayoutManager.
                        **mRecyclerView.getLayoutManager().startSmoothScroll(smoothScroller);**
0
Paras Santoki

il suffit d'appeler cette méthode simplement:

((LinearLayoutManager)RecyclerView.getLayoutManager()).scrollToPositionWithOffset(yourItemPosition,0);

au lieu de:

RecyclerView.scrollToPosition(yourItemPosition);
0