La página de vista de lista anidada de vista de desplazamiento de Android tiene espacio en blanco adicional
En mi trabajo, me he encontrado muchas veces con el problema del ListView anidado de ScrollView. Hay muchas soluciones en Internet, pero no son completas. He probado muchos métodos diferentes y todos tienen pros y contras.
A continuación explicaré, analizaré y resumiré desde cuatro aspectos: las razones para usar la estructura ListView anidada de ScrollView, los problemas encontrados en la estructura, varias soluciones y la comparación de ventajas y desventajas.
De hecho, no es solo ListView, sino también otras clases heredadas de AbsListView, incluidas ExpandableListView, GridView, etc. Para facilitar la explicación, a continuación se utiliza ListView.
I. ¿Por qué utilizar la estructura peculiar de ScrollView para anidar ListView?
ScrollView y ListView son estructuras de desplazamiento. Como sugieren los nombres, las funciones de estos dos controles en la interfaz de usuario son. Lo mismo, pero mire el diseño a continuación:
Esta es la página de confirmación del pedido de Tmall Mall. ScrollView está anidado en ExpandableListView. Hay una cantidad fija de controles en ExpandableListView y una cantidad fija de controles en la parte inferior. Todo se puede desplazar. Los datos de la lista deben anidarse dentro de datos fijos y desplazarse juntos como un todo. Bajo este requisito de diseño, apareció la extraña estructura de ListView anidado de ScrollView.
2. Problemas encontrados en estructuras anidadas de ScrollView y ListView
Sin más, veamos los ejemplos de fallos:
android: id="@+id/act_solution_1_sv" android:layout_width="fill_parent" android:layout_height="fill_parent"> < LinearLayout android: android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation=" vertical"> android:layout_width="fill_parent" android:layout_height="wrap_content" android:text ="/nListView encima de los datos\n" < ;ListView android:id="@+id/act_solution_1_lv" android:layout_width="fill_parent " android:layout_height="wrap_content"> android:layout_width="fill_parent" android:layout_height="wrap _content" android:text="\nListView debajo de los datos\n"
ScrollView solo puede colocar un control, generalmente un LinearLayout, y establecer la propiedad de dirección en vertical mientras representa el contenido en LinearLayout. A simple vista, no debería haber ningún problema. Pero mire el efecto real en la siguiente imagen:
El cuadro negro en la imagen es ListView, que coloca 20 datos, pero solo muestra 1.
No hay nada malo en configurar las propiedades de un control, pero ¿por qué no se comporta como quiero?
Por favor, mira la siguiente imagen:
¿Tiene esto sentido? La razón es el costo de manejar eventos de desplazamiento y establecer la altura del control ListView.
Aunque he leído mucho código fuente, no sé por dónde empezar. Sé aproximadamente el motivo, pero no tengo idea de cómo organizarlo. Solicitando orientación experta...
3. Solución al problema
1 Establezca manualmente la altura de ListView
Después de las pruebas, se descubrió que el ListView se puede especificar directamente en xml. La altura puede resolver este problema, pero los datos en ListView son variables y también es necesario medir la altura real. Por lo tanto, surgió el código para establecer manualmente la altura de ListView.
/**
* Establecer dinámicamente la altura de ListView
* @param listView
*/
público estático vacío setListViewHeightBasedOnChildren(ListView listView) {
if (listView == null) return;
ListAdapter listAdapter = listView.getAdapter();
if ( listAdapter == null) {
// condición previa
return;
}
int altura total = 0; p >
for (int i = 0; i < listAdapter.getCount(); i++) {
Ver listItem = listAdapter.getView(i, null); listItem = listAdapter.getView(i, null);
Ver listItem = listAdapter.getView(i, null)getView(i, null, listView);
listItem.measure(0 , 0);
altura total += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight());
return convertView;
}
En Activty, simplemente configure directamente un adaptador personalizado.
lv = (ListView) findViewById(R.id.act_solution_2_lv);
adapter = new AdapterForListView2(this);
lv.setAdapter(adapter);
3. Utilice LinearLayout en lugar de ListView
Dado que ListView no puede adaptarse a ScrollView, cambie a un control que pueda adaptarse a ScrollView. ¿Por qué tiene que conservar el árbol ListView? LinearLayout es la mejor opción. ¿Pero qué pasa si también quiero utilizar el Adater ya definido? Solo necesitamos personalizar una clase que hereda de LinearLayout y agregar un adaptador para BaseAdapter.
importar android.content.Context;
importar android.util.AttributeSet;
importar android.util.Log;
importar android.Content.Context;
importar android.util.AttributeSet;
importar android.util.Log;
importar android.Content.View; p>
p>