RecyclerView
をスムーズに自動スクロールして、ユーザーがRecyclerViewのすべての要素を表示し、ニュースフィードなどのように最初からもう一度スクロールできるようにする方法。
smoothScrollToPosition()
とscrollToPosition()
は知っていますが、最後の要素までスクロールが速すぎてしまいます。
RecyclerViewをアニメーション化し、ゆっくりと動かしたい。
答えを少し改善するために、スムーズなアニメーションで無限大を自動スクロールします。
final int speedScroll = 1200;
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
int count = 0;
boolean flag = true;
@Override
public void run() {
if(count < adapter.getItemCount()){
if(count==adapter.getItemCount()-1){
flag = false;
}else if(count == 0){
flag = true;
}
if(flag) count++;
else count--;
recyclerView.smoothScrollToPosition(count);
handler.postDelayed(this,speedScroll);
}
}
};
handler.postDelayed(runnable,speedScroll);
これはまさにあなたの答えですが、よりスムーズなアニメーションにリンクする場合は、LayoutManagerを使用してください
recyclerView.setLayoutManager(new CustomLinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
アニメーションの変更を制御しますMILLISECONDS_PER_INCH値。
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager(Context context) {
super(context);
}
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public CustomLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
final LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
private static final float MILLISECONDS_PER_INCH = 200f;
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return CustomLinearLayoutManager.this
.computeScrollVectorForPosition(targetPosition);
}
@Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
}
これが最善の解決策だと思います。
final int speedScroll = 150;
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
int count = 0;
@Override
public void run() {
if(count < list.size()){
recyclerView.scrollToPosition(++count);
handler.postDelayed(this,speedScroll);
}
}
};
handler.postDelayed(runnable,speedScroll);
試行錯誤の後、これは私にとって完璧に機能します
_ final RecyclerView mRecyclerViewr;
final ArrayList<String> stringArrayData = new ArrayList<String>
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerViewr.setLayoutManager(linearLayoutManager);
CustomAdapter customAdapter = new CustomAdapter(getApplicationContext(), topPriceBarList);
mRecyclerViewr.setAdapter(customAdapter);
// Auto Scroll Left To Right
final int scrollSpeed = 100; // Scroll Speed in Milliseconds
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
int x = 15; // Pixels To Move/Scroll
boolean flag = true;
// Find Scroll Position By Accessing RecyclerView's LinearLayout's Visible Item Position
int scrollPosition = linearLayoutManager.findLastCompletelyVisibleItemPosition();
int arraySize = stringArrayData.size(); // Gets RecyclerView's Adapter's Array Size
@Override
public void run() {
if (scrollPosition < arraySize) {
if (scrollPosition == arraySize - 1) {
flag = false;
} else if (scrollPosition <= 1) {
flag = true;
}
if (!flag) {
try {
// Delay in Seconds So User Can Completely Read Till Last String
TimeUnit.SECONDS.sleep(1);
mRecyclerViewr.scrollToPosition(0); // Jumps Back Scroll To Start Point
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Know The Last Visible Item
scrollPosition = linearLayoutManager.findLastCompletelyVisibleItemPosition();
mRecyclerViewr.smoothScrollBy(x, 0);
handler.postDelayed(this, scrollSpeed);
}
}
};
handler.postDelayed(runnable, scrollSpeed);
_
これにより、RecyclerViewが最後まで自動スクロールされ、1秒待ちます_(So User Can Read Till End)
_そしてジャンプ/最初の文字列にスクロールバック RecyclerViewの配列リスト内。正と負の方向に自動スクロールしたい場合You Just Need To Change The Condition Instead Of Using if(!flag) You Need To Set Value Of x in it
_ if (flag) x = 15;
else x= -15; // For Auto Scroll To Negative i.e Left Direction
_
Kotlinでの簡体字:
GlobalScope.launch(Dispatchers.Main, start = CoroutineStart.DEFAULT) {
var position = MINIMUM_POSITION
repeat(AUTO_SCROLL_REPEATING_TIMES) {
delay(SCROLL_DELAY)
rvBanners.smoothScrollToPosition(position)
when {
position+1 == listSize -> position = 0
position == 0 -> position = MINIMUM_POSITION
else -> position++
}
}
}
特定の時間に自動スクロールを開始する場合:
val job = GlobalScope.launch(Dispatchers.Main, start = CoroutineStart.LAZY) {
var position = MINIMUM_POSITION
repeat(AUTO_SCROLL_REPEATING_TIMES) {
delay(SCROLL_DELAY)
rvBanners.smoothScrollToPosition(position)
when {
position+1 == listSize -> position = 0
position == 0 -> position = MINIMUM_POSITION
else -> position++
}
}
}
...
job.start()
Recyclerviewをアダプタに設定した後、この方法で実装することもできます
final int duration = 10;
final int pixelsToMove = 263;
final Handler mHandler = new Handler(Looper.getMainLooper());
final Runnable SCROLLING_RUNNABLE = new Runnable() {
@Override
public void run() {
recyclerView.smoothScrollBy(pixelsToMove, 0);
mHandler.postDelayed(this, duration);
}
};
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int lastItem = horizontalLayoutManager.findLastCompletelyVisibleItemPosition();
if (lastItem == horizontalLayoutManager.getItemCount() - 1) {
mHandler.removeCallbacks(SCROLLING_RUNNABLE);
Handler postHandler = new Handler();
postHandler.postDelayed(new Runnable() {
@Override
public void run() {
quickTips.setAdapter(null);
quickTips.setAdapter(adapter);
mHandler.postDelayed(SCROLLING_RUNNABLE, 2000);
}
}, 2000);
}
}
});
mHandler.postDelayed(SCROLLING_RUNNABLE, 2000);
これは、Auto Scroll RecyclerViewおよびその100%が機能するための最良の方法です:
RecyclerView recyclerView = findViewById(R.id.rv_id);
final int time = 4000; // it's the delay time for sliding between items in recyclerview
final Adapter adapter = new Adapter(dataItems);
recyclerView.setAdapter(adapter);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(rootView.getContext(), LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
//The LinearSnapHelper will snap the center of the target child view to the center of the attached RecyclerView , it's optional if you want , you can use it
final LinearSnapHelper linearSnapHelper = new LinearSnapHelper();
linearSnapHelper.attachToRecyclerView(recyclerView);
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (linearLayoutManager.findLastCompletelyVisibleItemPosition() < (adapter.getItemCount() - 1)) {
linearLayoutManager.smoothScrollToPosition(recyclerView, new RecyclerView.State(), linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1);
}
else if (linearLayoutManager.findLastCompletelyVisibleItemPosition() == (adapter.getItemCount() - 1)) {
linearLayoutManager.smoothScrollToPosition(recyclerView, new RecyclerView.State(), 0);
}
}
}, 0, time);
private void hanldeAutoScroll() {
int position=0;
final int duration = 2000;
//final int pixelsToMove = 90;
final Handler mHandler = new Handler(Looper.getMainLooper());
final Runnable SCROLLING_RUNNABLE = new Runnable() {
@Override
public void run() {
position++;
if (position<urls.size())
{
recyclerView.scrollToPosition(position);
}else if (position==urls.size())
{
position=-1;
}
// recyclerView.smoothScrollBy(pixelsToMove, 0);
mHandler.postDelayed(this, duration);
}
};
mHandler.postDelayed(SCROLLING_RUNNABLE, 2000);
}