Ответ 1
Наконец, я смог заставить его работать! LinearLayoutManager.scrollToPositionWithOffset(int, int)
сделал трюк.
Я использую базовый RecyclerView с GridLayoutManager. Я заметил, что ни smoothScrollToPosition, ни scrollToPosition не работают правильно.
a) при использовании smoothScrollToPosition
я часто получаю ошибку от RecyclerView
"RecyclerView: пройденное положение цели при плавной прокрутке".
и RecyclerView
не прокручивается должным образом (часто он пропускает целевую строку). Это наблюдается в основном, когда я пытаюсь прокрутить до 1-го элемента некоторой строки
b) при использовании scrollToPosition
он работает нормально, но большую часть времени я вижу только первый элемент строки, а остальные не отображаются.
Можете ли вы дать мне несколько советов, как правильно работать, по крайней мере, один из методов?
Спасибо большое!
Наконец, я смог заставить его работать! LinearLayoutManager.scrollToPositionWithOffset(int, int)
сделал трюк.
У меня также есть одна проблема, но мне удалось исправить проблему, настроив SmoothScroller
введите Custom LayoutManager, как показано ниже
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);
}
}
(документация прокомментирована внутри приведенного выше кода). Установите указанный выше LayoutManager к recyerview
CustomLayoutManagerlayoutManager = new CustomLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.smoothScrollToPosition(position);
с помощью настраиваемого диспетчера макетов
scrollToPosition также хорошо работает в моем случае, вы можете использовать
recyclerView.scrollToPosition(position)
также, если вы хотите настроить скорость smoothScrollToPosition, пожалуйста, переопределите
private static final float MILLISECONDS_PER_INCH = 50f;
в CustomLayoutManager. Поэтому, если мы поместим значение как 1f, то smoothScrollToPosition будет быстрее, чем scrollToPosition.increasing значение make delay и убывание сделает скорость прокрутки. Надеюсь, это будет полезно.
В моем случае
`mRecyclerView.scrollToPosition(10);`
тоже не работает. Но
`mRecyclerView.smoothScrollToPosition(10);`
отлично работает для меня...
Чтобы прокрутить вниз до любой позиции в RecyclerView, нажмите EditText.
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);
}
});
Попробуйте измерить ширину или высоту элемента и вызовите smoothScrollBy (int dx, int dy).
Как выполнить плавную прокрутку и сохранить вертикальное положение RecyclerView
после поворота устройства: этот метод подходит для моего случая,
public class MainFragment extends Fragment { //OR activity it //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 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
Вызов recyclerView smoothScroll неэффективен, так как сам recyclerView не обрабатывает его макет.
Что вам нужно сделать, это вместо этого вызывать метод прокрутки макета менеджера.
Это должно выглядеть примерно так.
mRecyclerView.getLayoutManager().scrollToPosition(desiredPosition);
Если вы пытаетесь сделать быстрый переход к позиции вверху RecyclerView, просто используйте LinearLayoutManager.scrollToPositionWithOffset со значением 0 в качестве смещения.
Пример:
mLinearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLinearLayoutManager);
mLinearLayoutManager.scrollToPositionWithOffset(myPosition, 0);
smoothScrollToPosition очень медленный. Если вы хотите что-то быстрое, используйте scrollToPositionWithOffset.
когда вы используете scrollToPosition, он будет отображаться поверх окна рециркуляции.
Но если вы используете smoothScrollToPosition, он будет прокручиваться, пока не войдет в Window Visible. вот почему, пока smoothScrool к пункту ниже, он покажет его снизу
recyclerView.getLayoutManager(). smoothScrollToPosition (recyclerView, new RecyclerView.State(), currentPosition);