Smooth Scroll para GridView
¿ smoothScrollToPosition()
método smoothScrollToPosition()
para GridView
funciona correctamente? He encontrado un informe de error abierto y el mío no funciona correctamente.
setSelection()
está funcionando bien, pero quiero un efecto de desplazamiento suave.
- Android WebView desplazamiento suave
- Android: smoothScrollToPosition () no funciona correctamente
- RecyclerView no se desplaza como se esperaba
- Smooth desplazamiento recyclerview android
- (Smooth) ScrollToPosition no funciona correctamente con RecyclerView
¿Tiene alguna idea sobre este tema?
Si se trata de un problema persistente, ¿dónde debo empezar a implementar un buen efecto de desplazamiento?
- SmoothScrollToPosition no funciona?
- RecyclerView dentro de CoordinatorLayout, AppBarLayout Asunto de desplazamiento
- Personalizar RecyclerView LayoutManager no fling (sin problemas)
- Mejora de la suavidad de desplazamiento en un ListView de Android
Aunque no veo ningún problema al ejecutar el código de ejemplo que publicaste, si no ves resultados consistentes en tu aplicación, no es demasiado complicado crear tu propio controlador de desplazamiento. He aquí un ejemplo de implementación que podría usar:
private class ScrollPositioner { private static final int SCROLL_DURATION = 20; private static final int DIR_UP = 1; private static final int DIR_DOWN = 2; int mTargetPosition = AdapterView.INVALID_POSITION; int mDirection = AdapterView.INVALID_POSITION; int mLastSeenPosition = AdapterView.INVALID_POSITION; int mExtraScroll; GridView mGrid; public ScrollPositioner(GridView grid) { mGrid = grid; mExtraScroll = ViewConfiguration.get(mGrid.getContext()).getScaledFadingEdgeLength(); } Handler mHandler = new Handler(); Runnable mScroller = new Runnable() { public void run() { int firstPos = mGrid.getFirstVisiblePosition(); switch(mDirection) { case DIR_UP: { if (firstPos == mLastSeenPosition) { // No new views, let things keep going. mHandler.postDelayed(mScroller, SCROLL_DURATION); return; } final View firstView = mGrid.getChildAt(0); if (firstView == null) { return; } final int firstViewTop = firstView.getTop(); final int extraScroll = firstPos > 0 ? mExtraScroll : mGrid.getPaddingTop(); mGrid.smoothScrollBy(firstViewTop - extraScroll, SCROLL_DURATION); mLastSeenPosition = firstPos; if (firstPos > mTargetPosition) { mHandler.postDelayed(mScroller, SCROLL_DURATION); } break; } case DIR_DOWN: { final int lastViewIndex = mGrid.getChildCount() - 1; final int lastPos = firstPos + lastViewIndex; if (lastViewIndex < 0) { return; } if (lastPos == mLastSeenPosition) { // No new views, let things keep going. mHandler.postDelayed(mScroller, SCROLL_DURATION); return; } final View lastView = mGrid.getChildAt(lastViewIndex); final int lastViewHeight = lastView.getHeight(); final int lastViewTop = lastView.getTop(); final int lastViewPixelsShowing = mGrid.getHeight() - lastViewTop; final int extraScroll = lastPos < mGrid.getAdapter().getCount() - 1 ? mExtraScroll : mGrid.getPaddingBottom(); mGrid.smoothScrollBy(lastViewHeight - lastViewPixelsShowing + extraScroll, SCROLL_DURATION); mLastSeenPosition = lastPos; if (lastPos < mTargetPosition) { mHandler.postDelayed(mScroller, SCROLL_DURATION); } break; } default: break; } } }; public void scrollToPosition(int position) { mTargetPosition = position; mLastSeenPosition = AdapterView.INVALID_POSITION; if(position < mGrid.getFirstVisiblePosition()) { mDirection = DIR_UP; } else if (position > mGrid.getLastVisiblePosition()) { mDirection = DIR_DOWN; } else { return; } mHandler.post(mScroller); } }
Aquí hay un fragmento del ejemplo que enlazó que incluye dónde esta nueva clase para hacer el desplazamiento en lugar de la implementación del marco:
GridView g; boolean t= false; @Override public void onBackPressed() { //Instantiate and attach the custom positioner if(mPositioner == null) { mPositioner = new ScrollPositioner(g); } //Use the custom object to scroll the view mPositioner.scrollToPosition(0); if(t) { super.onBackPressed(); } else { t = true; } }
Si desea agregar una función donde la posición seleccionada siempre se desplaza hacia arriba incluso cuando la dirección de desplazamiento está hacia abajo, podría hacerlo. Esto no es algo que la implementación del marco está diseñado para hacer , pero se puede lograr agregando algún código en DIR_DOWN
para continuar desplazándose hasta que la primera posición visible coincida con la meta (como DIR_UP
). También debe tener cuidado con el caso en el que el desplazamiento termina antes de que la posición llegue a la parte superior, por lo que no está constantemente publicando el controlador en casos en los que nunca obtendrá un resultado diferente.
HTH
Tenía el mismo problema: construí un GridView simple y por alguna razón el smoothScrollToPosition()
no funcionó en absoluto (sólo rebotar de vez en cuando).
Después de la gran cantidad de depuración que resultan ser que tengo que eliminar el android:padding
parámetro de android:padding
de la GridView.
Muy extraño, realmente no sé por qué es así, pero al menos ahora funciona.