DolDurma
En mi RecyclerView
Tengo algunos elementos que el usuario puede desplazar y ver. Ahora quiero guardar esta posición y desplazarme después de volver. Este código a continuación devuelve 0 siempre y no puedo guardar eso:
recyclerMarketLists.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
recyclerViewCurrentScrolledPosition = recyclerMarketLists.getScrollY();
Log.e("Y: ", recyclerViewCurrentSceolledPosition + "");
}
});
el Logcat:
07-07 18:28:30.919 2124-2124/com.sample.presentationproject E/Y:: 0
joaquim ley
Está intentando obtener la información sobre el objeto equivocado. no es el RecyclerView
ni el Adapter
responsabilidad sino el LayoutManager de RecyclerView.
En lugar del genérico ViewTreeObserver.OnScrollChangedListener()
Recomendaría agregar en su lugar el RecyclerView.OnScrollListener
y usa el onScrollStateChanged(RecyclerView recyclerView, int newState)
devolución de llamada que le da la newState
Deberías usar SCROLL_STATE_IDLE
para buscar su posición. Sentido:
yourRecyclerView.getLayoutManager().findFirstVisibleItemPosition();
Como señaló Rik van Velzen, probablemente necesite lanzar su
LayoutManager
a unLinearLayoutManager
oGridLayoutManager
(tienes que transmitir al tipo correcto que estás usando) para acceder a estos
findVisibleXXXX()
métodos.
En dicho método de devolución de llamada. Espero haber dejado esto lo suficientemente claro para usted, puede encontrar documentación sobre las clases aquí:
respuesta de yigit (Google) en posiciones visibles
-
linearLayoutManager.scrollToPositionWithOffset(intemIndex, pxFromTop); Si fue útil, favor de votar mi respuesta.
– Joaquín Ley
7 julio 2016 a las 16:19
-
es esto correcto:
recyclerView.scrollToPosition(recyclerViewLastPosition);
– Dol Durma
7 julio 2016 a las 16:37
-
Sí. También puede usar smoothScroll para efectos visuales
– Joaquín Ley
28 de noviembre de 2017 a las 14:24
-
Cuando llamo al
scrollToPosition
nunca termina de desplazarse. ¿Alguna pista?– pamobo0609
9 de mayo de 2018 a las 16:46
-
Es posible que deba convertir LayoutManager en Linear o GridLayoutManager, etc. al llamar a getLayoutManager() para poder llamar a findFirstVisibleItemPosition()
–Rik van Velzen
13 de julio de 2018 a las 8:12
gracias por la solución joaquim ley. Esto ayuda a crear recyclerView
horizontal
buscapersonas sin utilizar ninguna biblioteca.
En eso recyclerView
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vocabulary_list);
// Set up the recyclerView with the sections adapter.
mRecyclerView = findViewById(R.id.list);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
mRecyclerView.setAdapter(new VocabularyListAdapter<>(vocabularyList));
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE){
int position = getCurrentItem();
onPageChanged(position);
}
}
});
PagerSnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(mRecyclerView);
}
public boolean hasPreview() {
return getCurrentItem() > 0;
}
public boolean hasNext() {
return mRecyclerView.getAdapter() != null &&
getCurrentItem() < (mRecyclerView.getAdapter().getItemCount()- 1);
}
public void preview() {
int position = getCurrentItem();
if (position > 0)
setCurrentItem(position -1, true);
}
public void next() {
RecyclerView.Adapter adapter = mRecyclerView.getAdapter();
if (adapter == null)
return;
int position = getCurrentItem();
int count = adapter.getItemCount();
if (position < (count -1))
setCurrentItem(position + 1, true);
}
private int getCurrentItem(){
return ((LinearLayoutManager)mRecyclerView.getLayoutManager())
.findFirstVisibleItemPosition();
}
private void setCurrentItem(int position, boolean smooth){
if (smooth)
mRecyclerView.smoothScrollToPosition(position);
else
mRecyclerView.scrollToPosition(position);
}
-
Muchas gracias, déjame comprobarlo 🙂
– Dol Durma
9 de junio de 2018 a las 18:58
-
PagerSnapHelper controla el desplazamiento de elemento a elemento como ViewPger
– Vahe Gharibian
10 de junio de 2018 a las 23:16
-
Me alegro de haber podido ayudar, aunque parece que estás creando objetos cada vez que tu
RecyclerView
se toca, no estoy seguro de que este sea el más eficaz.– Joaquín Ley
17 de julio de 2018 a las 13:21
Mattia Ferigutti
Esta es la función de extensión en Kotlin:
fun RecyclerView?.getCurrentPosition() : Int {
return (this?.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
}
Puede usarlo simplemente invocando esta función en su RecyclerView
:
val position = yourRecyclerView.getCurrentPosition()
-
no es aconsejable dirigir el reparto a través de
as
y use!!
. en su lugar, conversión anulable a través deas?
seguido de elvis (?:0
) es mucho más seguro– ansh sachdeva
11 mayo 2021 a las 16:27
Prueba esto en Kotlin:
myRecyclerView.addOnScrollListener(object: RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val offset: Int = myRecyclerView.computeHorizontalScrollOffset()
if (offset % myRecyclerView.width == 0) {
val position: Int = offset / myRecyclerView.width
Log.e("Current position is", position.toString())
}
}
})
P Toles
Hice 7 cambios en mi MainActivity y obtuve resultados perfectos en píxeles. Mi recyclerview SIEMPRE recuerda su estado anterior cuando regresa de alguna otra actividad (por ejemplo, DetailActivity).
Paso 1: Inicializa el administrador de diseño así:
// Initialize the layout manager
moviePosterLayoutManager = (moviePosterRecyclerView.getLayoutManager() == null) ?
new GridLayoutManager(this, numberOfColumns) : moviePosterRecyclerView.getLayoutManager();
// create a new layoutManager // reuse the existing layoutManager
Paso 2: dentro de su clase MainActivity, cree una variable STATIC para mantener el estado de su administrador de diseño mientras realiza la transición entre actividades:
private static Parcelable layoutManagerState;
Paso 3: también cree esta constante dentro de MainActivity ():
Cadena final estática pública KEY_LAYOUT_MANAGER_STATE = “layoutManagerState”;
Paso 4: dentro del método onCreate para su MainActivity, realice la siguiente prueba (es decir,
protected void onCreate(@Nullable final Bundle savedInstanceState) {....
if (layoutManagerState != null) {
//moviePosterLayoutManager
moviePosterLayoutManager.onRestoreInstanceState(layoutManagerState);
moviePosterRecyclerView.setLayoutManager(moviePosterLayoutManager);
} else {
moviePosterRecyclerView.setLayoutManager(moviePosterLayoutManager);
moviePosterRecyclerView.scrollToPosition(moviePosition);
// the default position
}
Paso 5: en su método onSaveInstanceState, asegúrese de guardar su layoutManagerState como un paquete de la siguiente manera:
vacío protegido onSaveInstanceState(Bundle outState) {
layoutManagerState = moviePosterLayoutManager.onSaveInstanceState();
// Save currently selected layout manager.
outState.putParcelable(KEY_LAYOUT_MANAGER_STATE,layoutManagerState);
}
Paso 6: Coloque un código similar en el método onResume() de MainActivity:
protected void onResume() {
super.onResume();
if (layoutManagerState != null) {
moviePosterLayoutManager.onRestoreInstanceState(layoutManagerState);
}
}
Paso 7: Recuerde que todo este código se colocó dentro de mi archivo MainActivity.java. Es importante recordar que el administrador de diseño es responsable de mantener la posición de desplazamiento de la vista del reciclador. Por lo tanto, guardar el estado del administrador de diseño es de suma importancia. El código podría modularizarse y colocarse dentro de una vista de reciclador personalizada, pero descubrí que esto es más fácil de implementar para mí.
-
Esto funcionó muy bien para mí: el píxel perfecto fue correcto.
– usuario3479586
04/08/2019 a las 20:20
-
¿De dónde obtienes el valor moviePosition?
– usuario1801605
24 de octubre de 2019 a las 0:12
latapa
Para un requisito similar más alguna acción necesaria para realizar en el cambio de estado de desplazamiento, hice esto con un oyente de desplazamiento personalizado:
class OnScrollListener(private val action: () -> Unit) : RecyclerView.OnScrollListener() {
private var actionExecuted: Boolean = false
private var oldScrollPosition: Int = 0
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
when (newState) {
RecyclerView.SCROLL_STATE_DRAGGING -> actionExecuted = false
RecyclerView.SCROLL_STATE_SETTLING -> actionExecuted = false
RecyclerView.SCROLL_STATE_IDLE -> {
val scrolledPosition =
(recyclerView.layoutManager as? LinearLayoutManager)?.findFirstVisibleItemPosition() ?: return
if (scrolledPosition != RecyclerView.NO_POSITION && scrolledPosition != oldScrollPosition && !actionExecuted) {
action.invoke()
actionExecuted = true
oldScrollPosition = scrolledPosition
}
}
}
}
}
Esto se debe al error preexistente con RecyclerView onScroll que activa la devolución de llamada 2-3 o incluso más veces. Y si hay alguna acción que realizar, terminará ejecutándose varias veces.
-
Esto funcionó muy bien para mí: el píxel perfecto fue correcto.
– usuario3479586
04/08/2019 a las 20:20
-
¿De dónde obtienes el valor moviePosition?
– usuario1801605
24 de octubre de 2019 a las 0:12
Alguacil fiscal de Tippu
En mi caso, necesito mi vista de posición actual en Actividad, así que creo un método de devolución de llamada y uso el siguiente método.
Agrega este código en el Adaptador class para obtener la posición actual de la vista.
Agrega esto en onBindViewHolder método.
holder.imgProductParts.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
onPositionChangeListener.onItemChanged(position);
}
@Override
public void onViewDetachedFromWindow(View v) { }
});