programacion - manual de android en pdf
Altura lĂmite de ListView en Android (16)
Quiero mostrar un botón debajo de un ListView
. El problema es que si ListView
se extiende (elementos agregados ...), el botón se saca de la pantalla.
LinearLayout
un LinearLayout
con pesas (como se sugiere en Android: ¿por qué no hay maxHeight para una vista? ), Pero o bien obtuve los pesos incorrectos o simplemente no funcionó.
Además, encontré en algún lugar la pista para usar un RelativeLayout
. El ListView
se establecería encima del botón con el android:layout_above
param.
El problema con esto es que no sé cómo colocar el botón después. En el ejemplo que encontré, la Vista debajo del ListView
se ajustó usando android:layout_alignParentBottom
, pero no quiero que mi botón se adhiera a la parte inferior de la pantalla.
¿Alguna idea aparte de usar setHeight-method y algunos cálculos del espacio requerido?
Editar: obtuve muchas respuestas útiles.
La solución de bigstone y user639183 casi funcionó a la perfección. Sin embargo, tuve que agregar un relleno extra / margen en la parte inferior del botón, ya que todavía se empujaría a mitad de la pantalla (pero luego se detuvo)
La respuesta de Adinia con el diseño relativo solo está bien si desea que el botón se fije en la parte inferior de la pantalla. No es lo que pretendía pero aún podría ser útil para otros.
La solución de AngeloS fue la que elegí al final, ya que acaba de crear los efectos que quería. Sin embargo, hice dos pequeños cambios en el
LinearLayout
alrededor del botón:Primero, como no quería tener valores absolutos en mi diseño, cambié
android:layout_height="45px"
porwrap_content
, que también funciona bien.Segundo, como quería que el botón se centrara horizontalmente, lo cual solo es compatible con
LinearLayout
vertical, cambié android: orientation = "horizontal" a "vertical".
AngeloS también declaró en su publicación inicial que no estaba seguro de si el
android:layout_weight="0.1"
en elLinearLayout
alrededor delListView
tuvo algún efecto; ¡Lo intenté y realmente lo hace! Sin, el botón sale de la pantalla de nuevo.
Como no hay ningún atributo MaxHeight, la mejor opción es establecer la altura del ListView en un valor establecido o usar wrap_content
.
Con LinearLayout
, establezca la altura de su ListView
y Button
en wrap_content
y agregue un peso = 1 a ListView
. Esto debería funcionar como lo desees.
Y sí, establezca el layout_gravity
del Button
en la bottom
En su última edición, solo tiene que agregar android:layout_above="@+id/butt1"
en su código ListView.
Y para mostrarle (y a todos los que aquí trataron una respuesta anterior) que realmente no necesita usar más de un RelativeLayout
, aquí está su código corregido :
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bkg">
<TextView
android:id="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="TextView1"
android:layout_alignParentTop="true">
</TextView>
<TextView
android:id="@+id/textView2"
android:layout_below="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="TextView2"
android:layout_centerHorizontal="true">
</TextView>
<Button
android:id="@+id/butt1"
android:text="string/string3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true">
</Button>
<ListView
android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dip"
android:layout_marginBottom="2dip"
android:drawSelectorOnTop="false"
android:visibility="visible"
android:layout_below="@+id/textView2"
android:layout_above="@+id/butt1" />
</RelativeLayout>
y el resultado , usando una lista aleatoria:
Encontré una forma de hacerlo sin usar contenedores anidados, inspirados en la solución de AngeloS.
LinearLayout
con orientación vertical, que tiene un ListView
y un botón. Configuro el android:layout_weight="0.1"
para el ListView
.
Logra que el botón permanezca siempre al final de la lista. Y el botón no se desplaza de la pantalla cuando la lista crece.
<ListView
android:id="@+id/notes_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1"
/>
<Button
android:id="@+id/create_note_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onCreateButtonClicked"
android:text="@string/create_notes"
/>
Esta es la forma más limpia de hacerlo:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ListView
android:id="@+id/ListView01"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:dividerHeight="2px">
</ListView>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/drawable"
>
<Button android:background="@drawable/btn_more2"
android:id="@+id/moreButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingRight="20px"
/>
</LinearLayout>
</LinearLayout>
Es similar a la solución de Angelos, pero no necesita la distribución lineal que envuelve ListView. También puede usar un FrameLayout que es más liviano que un LinearLayout para cerrar el Botón.
Intenta usar RelativeLayout con el botón en la parte inferior. Establezca la altura del diseño como "wrap_content". No lo he intentado. Solo idea
La idea se resume en las muy buenas soluciones por:
- AngeloS
- Sparkle
Ambos parecen funcionar perfectamente al menos en v4.4.3.
Todavía tuve que dedicar algo de tiempo a escribir el código de prueba para verificarlo y confirmar cada método. A continuación se muestra el código de prueba mínimo autónomo requerido.
El diseño se basa en la solución de Sparkle, ya que contiene menos diseño anidado. También se ha actualizado para reflejar las comprobaciones actuales de LINT.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context="MainActivity" >
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Grow List"
tools:ignore="HardcodedText" />
</LinearLayout>
La actividad proporciona el código repetitivo para probar la solución por ti mismo.
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listview = (ListView)findViewById(R.id.listview);
final ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
new ArrayList<String>());
adapter.setNotifyOnChange(true);
listview.setAdapter(adapter);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
int count = adapter.getCount();
adapter.add(String.valueOf(count));
listview.setSelection(count);
}
});
}
}
Siéntase libre de agregar o mejorar, ya que se trata de "wiki de la comunidad".
Lo resolví poniendo ListView dentro de ScrollView. A Lint no le gustó, pero al agregar un minHeight y configurar el fillViewport en verdadero, tengo un buen resultado.
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:minHeight="100dp"
android:fillViewport="true"
android:fadeScrollbars="false"
android:paddingTop="2dp"
android:orientation="vertical"
android:scrollbarAlwaysDrawVerticalTrack="true" >
<ListView
android:id="@+id/workoutAElistRoutines"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="fill_vertical"
android:background="@drawable/dialog_inner_border_tan"
android:choiceMode="singleChoice"
android:orientation="vertical"
android:paddingLeft="3dp"
android:paddingRight="3dp" >
</ListView>
</ScrollView>
Lo siguiente fue lo que funcionó para mí ...
if(adapter.getCount() > 3){
View item = adapter.getView(0, null, impDateListView);
item.measure(0, 0);
LayoutParams params = impDateListView.getLayoutParams();
params.width = LayoutParams.MATCH_PARENT;
params.height = 3 * item.getMeasuredHeight();
impDateListView.setLayoutParams(params);
}
Nota: Params.width = ... Necesita establecerse también ...
El ejemplo anterior es cuando usa TableRow y ListView dentro de TableRow ...
Probablemente puedas hacer que esto funcione usando contenedores anidados. Es posible que deba envolver el Botón en un segundo contenedor (interno) para que ocupe más espacio, y simplemente alinee el Botón en la parte superior del contenedor interno.
Posible algo como esto:
Disposición relativa
-- Vista de la lista
-- Disposición relativa
---- Botón
Usando las diferentes opciones de alineación en los dos contenedores, debería poder hacer que esto funcione.
Resolví este problema en el código, estableciendo la altura de la vista de lista solo si tiene más de 5 elementos:
if(adapter.getCount() > 5){
View item = adapter.getView(0, null, listView);
item.measure(0, 0);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, (int) (5.5 * item.getMeasuredHeight()));
listView.setLayoutParams(params);
}
Tenga en cuenta que establezco la altura máxima en 5,5 veces la altura de un solo elemento, por lo que el usuario sabrá con seguridad que hay algo de desplazamiento que hacer. :)
Si desea que el contenido debajo de la vista de lista se mueva hacia abajo a medida que los elementos se agregan a la lista, intente con esta solución:
Agregue relleno positivo en la parte inferior de la vista de lista y relleno negativo en la parte superior del "pie de página". Esto funcionará en un diseño lineal o un diseño relativo.
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="50dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-50dp"/>
Tuve este problema exacto y para resolverlo creé dos LinearLayouts
separados para alojar el ListView
y el Button
respectivamente. A partir de ahí puse ambos en otro Linear Layout
y establecí la android:orientation
ese contenedor en android:orientation
vertical
. También establecí el peso del LinearLayout
que contenía el ListView
en 0.1
pero no sé si eso tiene algún efecto. Desde allí, puede establecer la altura del contenedor inferior (que tiene su botón) a la altura que desee.
EDITAR esto es lo que quiero decir:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1"
>
<ListView android:id="@+id/ListView01"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:dividerHeight="2px">
</ListView>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="45px"
android:background="@drawable/drawable"
>
<Button android:background="@drawable/btn_more2"
android:id="@+id/moreButton"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:paddingRight="20px"
/>
</LinearLayout>
</LinearLayout>
La solución anterior fijará el botón en la parte inferior de la pantalla.
Para que el botón flote en la parte inferior de la lista, cambie la altura de ListView01
a wrap_content
:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.1"
>
<ListView android:id="@+id/ListView01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:dividerHeight="2px">
</ListView>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="45px"
android:background="@drawable/drawable"
>
<Button android:background="@drawable/btn_more2"
android:id="@+id/moreButton"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:paddingRight="20px"
/>
</LinearLayout>
</LinearLayout>
en LinearLayout, simplemente agrega android:layout_weight="1"
para ti ListView
envolver contenido en diseño lineal
en la vista de lista agregar: android: layout_weight = "1"
en su botón establece altura fija
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ListView
android:id="@+id/my_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</ListView>
<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="50dp"/>
</LinearLayout>
RelativeLayout
es una solución, si no desea que el botón se quede demasiado cerca de la parte inferior, puede agregar márgenes (rellenar un botón lo rompería porque usa un fondo de 9 parches y establece su propio relleno).
Sería lo mismo si utilizara LinearLayout
: la manera de lograr lo que desea es establecer ListView
en una altura = 0 y weight = 1, y para la altura del botón = wrap_content y weight = 0. (establecer ambos en wrap_content, como dijo user639183, no limitaría la altura de ListView
).