Прокрутите RecyclerView, чтобы показать выбранный элемент сверху
Я ищу способ прокрутки RecyclerView
чтобы показать выбранный элемент сверху.
на ListView
я смог сделать это, используя scrollTo(x,y)
и получение верхней части элемента, который должен быть центрирован.
что-то типа:
@Override
public void onItemClick(View v, int pos){
mylistView.scrollTo(0, v.getTop());
}
проблема в том, что RecyclerView
возвращает ошибку при использовании это scrollTo
способ сказать
RecyclerView не поддерживает прокрутку до абсолютной позиции
как может Я прокручиваю RecyclerView
чтобы поместить выбранный элемент в верхнюю часть представления?
12 ответов
Если вы используете LinearLayoutManager или StaggeredGridLayoutManager, у каждого из них есть scrollToPositionWithOffset метод, который принимает как положение, так и смещение начала элемента с начала RecyclerView, который, похоже, выполнит то, что вам нужно (установка смещения на 0 должна совпадать с верхней).
например:
//Scroll item 2 to 20 pixels from the top
linearLayoutManager.scrollToPositionWithOffset(2, 20);
Если вы ищете вертикальный LinearLayout Manager, вы можете добиться плавной прокрутки с помощью пользовательского LinearSmoothScroller
:
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;
}
}
}
используйте экземпляр layoutmanager в представлении recycle, а затем вызовите recyclerView.smoothScrollToPosition(pos);
сгладит прокрутку до выбранной позиции в верхней части представления recycler
вам просто нужно позвонить recyclerview.scrollToPosition(position)
. Это прекрасно!
Если вы хотите вызвать его в адаптере, просто пусть ваш адаптер имеет экземпляр recyclerview или действие или фрагмент, который содержит recyclerview, чем реализует метод getRecyclerview()
в них.
Я надеюсь, это может помочь вам.
то же самое с регулятор скорости
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;
}
}
}
попробуйте то, что сработало для меня круто!
создать переменную private static int displayedposition = 0;
Теперь для позиции вашего RecyclerView в вашей деятельности.
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();
}
});
поместите эту инструкцию туда, где вы хотите разместить бывший сайт, отображаемый в вашем представлении .
LinearLayoutManager llm = (LinearLayoutManager) mRecyclerView.getLayoutManager();
llm.scrollToPositionWithOffset(displayedposition , youList.size());
Ну вот и все, это сработало отлично для меня \o/
что я сделал, чтобы восстановить положение прокрутки после обновления RecyclerView на кнопку нажал:
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);
получение смещения первого видимого элемента сверху перед созданием объекта linearLayoutManager и после его создания вызывался объект scrollToPositionWithOffset объекта LinearLayoutManager.
прокрутка в определенной позиции
и это мне очень помогло.
с помощью click listener вы можете получить позицию в вашем адаптере
layoutmanager.scrollToPosition(int position);
В моем случае мой RecyclerView
есть отступ сверху такой
<android.support.v7.widget.RecyclerView
...
android:paddingTop="100dp"
android:clipToPadding="false"
/>
затем для прокрутки элемента вверх, мне нужно
recyclerViewLinearLayoutManager.scrollToPositionWithOffset(position, -yourRecyclerView.getPaddingTop());
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);**
просто вызовите этот метод просто:
((LinearLayoutManager)RecyclerView.getLayoutManager()).scrollToPositionWithOffset(yourItemPosition,0);
вместо:
RecyclerView.scrollToPosition(yourItemPosition);
Я использую код ниже, чтобы плавно прокрутить элемент (thisView) наверх.
Он также работает для GridLayoutManager с видами разной высоты:
View firstView = mRecyclerView.getChildAt(0);
int toY = firstView.getTop();
int firstPosition = mRecyclerView.getChildAdapterPosition(firstView);
View thisView = mRecyclerView.getChildAt(thisPosition - firstPosition);
int fromY = thisView.getTop();
mRecyclerView.smoothScrollBy(0, fromY - toY);
Кажется, работает достаточно хорошо для быстрого решения.