Ik gebruik standaard RecyclerView met GridLayoutManager. Ik merkte op dat noch smoothScrollToPosition noch scrollToPosition correct werkt.
a) bij gebruik van smoothScrollToPosition
krijg ik vaak een foutmelding van RecyclerView
“RecyclerView﹕ Gepasseerd over doelpositie tijdens soepel scrollen.”
en RecyclerView
wordt niet goed gescrolld (vaak mist het de beoogde rij). Dit wordt meestal waargenomen wanneer ik naar het eerste item van een rij probeer te scrollen
b) bij gebruik van scrollToPosition
lijkt het redelijk goed te werken, maar meestal kan ik alleen het eerste item van de rij zien en de rest wordt niet weergegeven.
Kun je me wat hints geven hoe ik tenminste één van de methoden goed kan laten werken?
Hartelijk dank!
Antwoord 1, autoriteit 100%
Eindelijk lukte het me om het te laten werken! LinearLayoutManager.scrollToPositionWithOffset(int, int)
deed het.
Antwoord 2, autoriteit 23%
Ik heb hetzelfde probleem, maar heb het probleem kunnen oplossen door SmoothScroller aan te passen
laat Custom LayoutManager zoals hieronder
public class CustomLayoutManager extends LinearLayoutManager {
private static final float MILLISECONDS_PER_INCH = 50f;
private Context mContext;
public CustomLayoutManager(Context context) {
super(context);
mContext = context;
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView,
RecyclerView.State state, final int position) {
LinearSmoothScroller smoothScroller =
new LinearSmoothScroller(mContext) {
//This controls the direction in which smoothScroll looks
//for your view
@Override
public PointF computeScrollVectorForPosition
(int targetPosition) {
return CustomLayoutManager.this
.computeScrollVectorForPosition(targetPosition);
}
//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);
}
}
(documentatie becommentarieerd in de bovenstaande code)Stel de bovenstaande LayoutManager in
naar de recyerview
CustomLayoutManagerlayoutManager = new CustomLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.smoothScrollToPosition(position);
met behulp van de aangepaste lay-outmanager
scrollToPosition
werkt ook goed in mijn geval die je kunt gebruiken
recyclerView.scrollToPosition(position)
ook als je de snelheid van smoothScrollToPosition wilt aanpassen, overschrijf dan de
private static final float MILLISECONDS_PER_INCH = 50f;
in CustomLayoutManager.
Dus als we de waarde als 1fplaatsen, zal smoothScrollToPosition sneller zijn, zoals scrollToPosition. toenemende waarde maakt vertraging en afnemende maakt de snelheid van scrollen.
Ik hoop dat dit nuttig zal zijn.
Antwoord 3, autoriteit 17%
In mijn geval,
mRecyclerView.scrollToPosition(10);
werkte ook niet.
Maar
mRecyclerView.smoothScrollToPosition(10);
werkt prima voor mij…
Antwoord 4, autoriteit 10%
Om soepel naar beneden te scrollen vanuit elke positie in de RecyclerView door op EditText te klikken.
edittext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
rv_commentList.postDelayed(new Runnable() {
@Override
public void run() {
rv_commentList.scrollToPosition(rv_commentList.getAdapter().getItemCount() - 1);
}
}, 1000);
}
});
Antwoord 5, autoriteit 9%
Een andere reden waarom een van de bovengenoemde oplossingen mogelijk niet werkt, is als uw RecyclerView is ingesloten in een NestedScrollView. In dit geval moet je de scroll-actie op de NestedScrollView aanroepen.
bijvoorbeeld:
nestedScrollview.smoothScrollTo(0,0)
Antwoord 6, autoriteit 4%
recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView,new RecyclerView.State(),currentPosition);
Antwoord 7
Probeer de breedte of hoogte van het item te meten en roep smoothScrollBy(int dx, int dy) aan.
Antwoord 8
Vloeiend scrollen uitvoeren en de verticale positie van RecyclerView
opslaan nadat het apparaat is gedraaid:
Dit is de methode die voor mijn geval werkt,
public class MainFragment extends Fragment { //OR activity it's //fragment in my case
....
@Override
public void onLoadFinished(@NonNull Loader<List<Report>> loader, List<Report> objects) { // or other method of your choice, in my case it's a Loader
RecyclerView recyclerViewRv = findViewById(........;
.....
recyclerViewRv.setAdapter(.....Your adapter);
recyclerViewRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
recyclerScrollY = recyclerViewRv. computeVerticalScrollOffset();
}
});
//Apply smooth vertical scroll
recyclerViewRv.smoothScrollBy(0,recyclerScrollY);
}
//Save vertical scroll position before rotating devices
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("recyclerScrollY",recyclerScrollY);
}
//BackUp vertical scroll position after rotating devices
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
recyclerScrollY = savedInstanceState.getInt("recyclerScrollY");
}
}
//If you want to perform the same operation for horizontal scrolling just add a variable called recyclerScrollX = recyclerScrollY = recyclerViewRv. computeHorizontalScrollOffset(); then save in bundle
Antwoord 9
Ik had een raar probleem waarbij smoothScrollToPosition
slechts af en toe werkte.
Na het plaatsen van de smoothScrollToPositionin de Handler Post
Vertraagdmet 1 seconde vertraging, het werkte prima.
Raadpleeg het volgende Kotlin-voorbeeld:
Handler().postDelayed({
recyclerViewObject.smoothScrollToPosition(0) // mention the position in place of 0
}, 1000) // 1000 indicates the 1 second delay.
Antwoord 10
Deze extensie is zo handig, probeer het alstublieft.
fun RecyclerView.smoothSnapToPosition(position: Int, snapMode: Int = LinearSmoothScroller.SNAP_TO_START) {
val smoothScroller = object : LinearSmoothScroller(this.context) {
override fun getVerticalSnapPreference(): Int = snapMode
override fun getHorizontalSnapPreference(): Int = snapMode
}
smoothScroller.targetPosition = position
layoutManager?.startSmoothScroll(smoothScroller)
}
Antwoord 11
Het aanroepen van de recyclerView smoothScroll is niet effectief, omdat de recyclerView zelf de lay-out niet aankan.
Wat u moet doen, is in plaats daarvan de scroll-methode van de lay-outmanager aanroepen.
Dit zou er ongeveer zo uit moeten zien
mRecyclerView.getLayoutManager().scrollToPosition(desiredPosition);
Antwoord 12
Als je snel naar een positie bovenaan de RecyclerView wilt scrollen, gebruik dan gewoon LinearLayoutManager.scrollToPositionWithOffset met 0 als offset.
Voorbeeld:
mLinearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLinearLayoutManager);
mLinearLayoutManager.scrollToPositionWithOffset(myPosition, 0);
smoothScrollToPosition is erg traag. Als je iets snel wilt, ga dan met scrollToPositionWithOffset.
Antwoord 13
wanneer u scrollToPositiongebruikt, wordt dit bovenaan de weergave van de recycler weergegeven.
Maar als je smoothScrollToPositiongebruikt, zal het scrollen totdat het in Window Visible komt. dat is de reden waarom, terwijl smoothScrool naar het item hieronder, het onderaan wordt weergegeven
Antwoord 14
Als je een RecyclerView in een NestedScrollView hebt, moet je beide regels gebruiken elke keer dat je naar het begin van de RecyclerView wilt gaan:
nestedScrollView.smoothScrollTo(0, 0);
layoutManager.scrollToPositionWithOffset(0, 0);
Dit werkt helemaal voor mij.
Antwoord 15
dit werkte voor mij
Handler().postDelayed({
(recyclerView.getLayoutManager() as LinearLayoutManager).scrollToPositionWithOffset( 0, 0)
}, 100)
Antwoord 16
Dus ik was op zoek naar een oplossing om terug te keren naar de top met een recyclerview in een andere lay-out die er bovenop heeft (in mijn geval had ik een LinearLayout met een TextView en mijn recyclerview erin). Hierdoor zou de smoothscroll maar tot halverwege het eerste item gaan.
Dit is wat ik deed wat heel goed werkt (Kotlin-oplossing):
back_to_top.setOnClickListener {
GlobalScope.launch(Dispatchers.Main) {
GlobalScope.launch(Dispatchers.Main) {
recyclerview.layoutManager?.smoothScrollToPosition(recyclerview, RecyclerView.State(), 0)
delay((recyclerview.layoutManager as LinearLayoutManager).findLastVisibleItemPosition() * 100L)
}.join()
recyclerview.scrollToPosition(0)
}
back_to_top.visibility = View.GONE
}
}
Wat ik doe, is dat ik vloeiend naar het eerste element scrol en het scrollen met 100 ms keer het laatste zichtbare item uitstel en vervolgens de scrollToPosition(0) aanroep (die naar de top.correctly gaat)
Antwoord 17
Geen van deze antwoorden werkte voor mij. Ik moest smoothScrollToPosition
maar @Ramz antwoord werkte niet. Ik merkte dat het constant zou overscrollen, maar slechts in één richting. Ik ontdekte dat het leek alsof de item-decorateurs het eraf gooiden. Ik had een horizontale lay-out en ik wilde na elk item een spatie toevoegen, behalve het laatste en die asymmetrie hield niet van. Zodra ik achter elk item een spatie plaatste, werkte het!