Önceki yanıtlardan herhangi birini seçmeniz durumunda, mevcut konumdan hedef konuma ulaşmak için gereken kaydırma miktarına göre gerçekten önemli ölçüde (ve kabul edilemeyecek şekilde) değişecek olan kaydırma süresi konusunu daha tam olarak ele almak istiyorum .
Tek tip bir kaydırma süresi elde etmek için hız (milisaniye başına piksel) her bir öğenin boyutunu hesaba katmalıdır - ve öğeler standart olmayan boyutta olduğunda, yepyeni bir karmaşıklık düzeyi eklenir.
Bu yüzden olabilir RecyclerView geliştiriciler konuşlandırılmış çok sert düzgün kaydırma bu hayati yönü için sepet.
Yarı tekdüze bir kaydırma süresi istediğinizi ve listenizin yarı tek tip öğeler içerdiğini varsayarsak, böyle bir şeye ihtiyacınız olacaktır.
/** Smoothly scroll to specified position allowing for interval specification. <br>
* Note crude deceleration towards end of scroll
* @param rv Your RecyclerView
* @param toPos Position to scroll to
* @param duration Approximate desired duration of scroll (ms)
* @throws IllegalArgumentException */
private static void smoothScroll(RecyclerView rv, int toPos, int duration) throws IllegalArgumentException {
int TARGET_SEEK_SCROLL_DISTANCE_PX = 10000; // See androidx.recyclerview.widget.LinearSmoothScroller
int itemHeight = rv.getChildAt(0).getHeight(); // Height of first visible view! NB: ViewGroup method!
itemHeight = itemHeight + 33; // Example pixel Adjustment for decoration?
int fvPos = ((LinearLayoutManager)rv.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
int i = Math.abs((fvPos - toPos) * itemHeight);
if (i == 0) { i = (int) Math.abs(rv.getChildAt(0).getY()); }
final int totalPix = i; // Best guess: Total number of pixels to scroll
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(rv.getContext()) {
@Override protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_START;
}
@Override protected int calculateTimeForScrolling(int dx) {
int ms = (int) ( duration * dx / (float)totalPix );
// Now double the interval for the last fling.
if (dx < TARGET_SEEK_SCROLL_DISTANCE_PX ) { ms = ms*2; } // Crude deceleration!
//lg(format("For dx=%d we allot %dms", dx, ms));
return ms;
}
};
//lg(format("Total pixels from = %d to %d = %d [ itemHeight=%dpix ]", fvPos, toPos, totalPix, itemHeight));
smoothScroller.setTargetPosition(toPos);
rv.getLayoutManager().startSmoothScroll(smoothScroller);
}
Not: Ben gün başladı küfür gelişigüzel dönüştürme ListView için RecyclerView .
protected int getHorizontalSnapPreference() { return LinearSmoothScroller.SNAP_TO_START; }
. Ayrıca soyut yöntemi uygulamalıydımpublic PointF computeScrollVectorForPosition(int targetPosition) { return layoutManager.computeScrollVectorForPosition(targetPosition); }
.