Ya no busques más en otros sitios ya que has llegado al sitio necesario, contamos con la solución que quieres recibir sin problemas.
Solución:
Encontré una solución que funciona de manera excelente y puede desplazar el ListView
sin problemas:
ListView lv = (ListView)findViewById(R.id.myListView); // your listview inside scrollview
lv.setOnTouchListener(new ListView.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
int action = event.getAction();
switch (action)
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
// Handle ListView touch events.
v.onTouchEvent(event);
return true;
);
Lo que esto hace es deshabilitar el TouchEvent
s en el ScrollView
y hacer el ListView
interceptarlos. Es simple y funciona todo el tiempo.
No deberías poner un ListView
dentro de una ScrollView
porque el ListView
la clase implementa su propio desplazamiento y simplemente no recibe gestos porque todos son manejados por el padre ScrollView
. Le recomiendo encarecidamente que simplifique su diseño de alguna manera. Por ejemplo, puede agregar las vistas que desea que se desplacen a la ListView
como encabezados o pies de página.
ACTUALIZAR:
A partir de API nivel 21 (Lollipop), los contenedores de desplazamiento anidados son oficialmente compatibles con el SDK de Android. Hay un montón de métodos en View
y ViewGroup
clases que proporcionan esta funcionalidad. Para que el desplazamiento anidado funcione en Lollipop, debe habilitarlo para una vista de desplazamiento infantil agregando android:nestedScrollingEnabled="true"
a su declaración XML o llamando explícitamente setNestedScrollingEnabled(true)
.
Si desea que el desplazamiento anidado funcione en dispositivos anteriores a Lollipop, lo que probablemente haga, debe usar las clases de utilidad correspondientes de la biblioteca de soporte. Primero tienes que reemplazarte ScrollView
con NestedScrollView. Este último implementa tanto NestedScrollingParent como NestedScrollingChild para que pueda usarse como contenedor de desplazamiento principal o secundario.
Pero ListView
no admite el desplazamiento anidado, por lo tanto, debe subclasificarlo e implementarlo NestedScrollingChild
. Afortunadamente, la biblioteca de soporte proporciona la clase NestedScrollingChildHelper, por lo que solo tiene que crear una instancia de esta clase y llamar a sus métodos desde los métodos correspondientes de su clase de vista.
También tengo una solución. Yo siempre utilizo este método. Prueba esto
Clase NestedListView.java:
public class NestedListView extends ListView implements OnTouchListener, OnScrollListener
private int listViewTouchAction;
private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99;
public NestedListView(Context context, AttributeSet attrs)
super(context, attrs);
listViewTouchAction = -1;
setOnScrollListener(this);
setOnTouchListener(this);
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE)
if (listViewTouchAction == MotionEvent.ACTION_MOVE)
scrollBy(0, -1);
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int newHeight = 0;
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY)
ListAdapter listAdapter = getAdapter();
if (listAdapter != null && !listAdapter.isEmpty())
int listPosition = 0;
for (listPosition = 0; listPosition < listAdapter.getCount()
&& listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++)
View listItem = listAdapter.getView(listPosition, null, this);
//now it will not throw a NPE if listItem is a ViewGroup instance
if (listItem instanceof ViewGroup)
listItem.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
listItem.measure(widthMeasureSpec, heightMeasureSpec);
newHeight += listItem.getMeasuredHeight();
newHeight += getDividerHeight() * listPosition;
if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize))
if (newHeight > heightSize)
newHeight = heightSize;
else
newHeight = getMeasuredHeight();
setMeasuredDimension(getMeasuredWidth(), newHeight);
@Override
public boolean onTouch(View v, MotionEvent event)
if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE)
if (listViewTouchAction == MotionEvent.ACTION_MOVE)
scrollBy(0, 1);
return false;
Puedes asentar nuestra misión exponiendo un comentario y puntuándolo te damos las gracias.