Je veux montrer un bouton sous une ListView
. Le problème, c'est que si la ListView
est étendue (éléments ajoutés ...), le bouton est poussé hors de l'écran.
J'ai essayé une LinearLayout
avec des poids (comme suggéré dans Android: pourquoi n'y a-t-il pas de maxHeight pour une vue? ), mais je me suis trompé ou j'ai tout simplement échoué.
En outre, j'ai trouvé quelque part la suggestion d'utiliser un RelativeLayout
. La ListView
serait alors définie au-dessus du bouton avec le paramètre Android:layout_above
.
Le problème avec ceci est que je ne sais pas comment positionner le bouton après. Dans l'exemple que j'ai trouvé, la vue située sous la ListView
a été ajustée à l'aide de Android:layout_alignParentBottom
, mais je ne veux pas que mon bouton s'accroche au bas de l'écran.
Des idées en dehors de l'utilisation de la méthode setHeight et du calcul de l'espace requis?
Edit: J'ai eu beaucoup de réponses utiles.
la solution de bigstone & user639183 presque fonctionnait parfaitement. Cependant, je devais ajouter une marge supplémentaire au bas du bouton, car il serait toujours poussé à mi-chemin hors de l'écran (puis arrêté
La réponse d'Adinia avec la disposition relative est satisfaisante si vous voulez que le bouton soit fixé au bas de l'écran. Ce n'est pas ce que je voulais, mais ça pourrait quand même être utile pour les autres.
La solution AngeloS est celle que j'ai choisie à la fin, car elle vient de créer les effets que je voulais. Cependant, j'ai apporté deux modifications mineures à la LinearLayout
autour du bouton:
Premièrement, comme je ne voulais pas avoir de valeurs absolues dans ma mise en page, j'ai changé Android:layout_height="45px"
en wrap_content
, ce qui fonctionne aussi très bien.
Deuxièmement, comme je voulais que le bouton soit centré horizontalement, ce qui n’est supporté que par LinearLayout
vertical, j’ai changé Android: orientation = "horizontal" en "vertical".
AngeloS a également déclaré dans son message initial qu'il n'était pas sûr si le Android:layout_weight="0.1"
param de la LinearLayout
autour de la ListView
avait un effet quelconque; Je viens d'essayer et c'est le cas! Sans cela, le bouton est à nouveau poussé hors de l'écran.
J'ai eu ce problème exact et pour le résoudre, j'ai créé deux variables LinearLayouts
distinctes pour abriter respectivement les variables ListView
et Button
. À partir de là, je mets les deux dans un autre Linear Layout
et je règle le Android:orientation
de ce conteneur sur vertical
. J'ai également réglé le poids de la LinearLayout
qui abritait la ListView
sur 0.1
mais je ne sais pas si cela a un effet. À partir de là, vous pouvez définir la hauteur du conteneur du bas (contenant le bouton) à la hauteur souhaitée.
EDITc'est ce que je veux dire:
<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 solution ci-dessus corrigera le bouton au bas de l'écran.
Pour que le bouton flotte en bas de la liste, modifiez la hauteur de ListView01
en 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>
J'ai résolu ce problème dans le code, en définissant height de listview uniquement s'il contient plus de 5 éléments:
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);
}
Remarquez que je règle la hauteur maximale à 5,5 fois la hauteur d'un seul élément, afin que l'utilisateur sache qu'il doit faire défiler! :)
Lors de votre dernière modification, il vous suffit d'ajouter également Android:layout_above="@+id/butt1"
dans votre code ListView.
Et pour vous montrer (et à tous ceux qui ont essayé une réponse plus tôt) que vous n'avez vraiment pas besoin d'utiliser plus d'un RelativeLayout
, voici votre code corrigé :
<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>
et le résultat , en utilisant une liste aléatoire:
En utilisant LinearLayout
, définissez la hauteur de votre ListView
et Button
sur wrap_content
et ajoutez un poids = 1 à ListView
. Cela devrait fonctionner comme vous voulez.
Et oui, définissez le layout_gravity
de la Button
sur bottom
RelativeLayout
est une solution. Si vous ne souhaitez pas que le bouton reste trop près du bas, vous pouvez ajouter des marges (le remplissage d'un bouton le casserait car il utilise un arrière-plan de 9 correctifs et définit son propre remplissage).
Ce serait la même chose si vous utilisiez une LinearLayout
: la manière d’atteindre ce que vous voulez est de définir la ListView
sur une hauteur = 0 et un poids = 1, et pour le bouton height = wrap_content et weight = 0. (définir les deux comme étant wrap_content, comme dit user639183, ne limiterait pas la hauteur de ListView
).
Nous avons trouvé un moyen de le faire sans utiliser de conteneurs imbriqués, inspirés de la solution AngeloS.
J'ai utilisé un LinearLayout
avec une orientation verticale, qui a un ListView
et un bouton. Je règle le Android:layout_weight="0.1"
pour la ListView
.
Il parvient toujours à placer le bouton au bas de la liste. Et le bouton ne sera pas poussé hors de l'écran lorsque la liste s'allongera.
<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"
/>
C'est la manière la plus propre de le faire:
<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>
C'est similaire à la solution d'Angelos mais vous n'avez pas besoin de la linéarité qui enveloppe le ListView. Vous pouvez également utiliser un FrameLayout plus léger que le LinearLayout pour boucler le bouton.
Vous pouvez probablement faire ce travail en utilisant des conteneurs imbriqués. Il est possible que vous deviez envelopper le bouton dans un deuxième conteneur (interne) pour qu'il prenne plus de place et aligner simplement le bouton sur le dessus du conteneur interne.
Possible quelque chose comme ça:
Disposition relative
- ListView
-- Disposition relative
---- Bouton
En utilisant les différentes options d'alignement sur les deux conteneurs, vous devriez pouvoir le faire fonctionner.
L'idée est décrite dans les très bonnes solutions par:
Ils semblent tous deux parfaitement fonctionner au moins sur la v4.4.3.
Il me restait encore du temps à écrire le code de test pour le vérifier et confirmer chaque méthode. Vous trouverez ci-dessous le code de test minimal et autonome requis.
La disposition est basée sur la solution de Sparkle, car elle contient moins de dispositions imbriquées. Également mis à jour pour refléter les vérifications LINT actuelles.
<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>
Activity fournit le code passe-partout pour tester la solution pour vous-même.
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);
}
});
}
}
N'hésitez pas à ajouter ou à améliorer car il s'agit d'un "wiki de communauté".
Essayez d'utiliser RelativeLayout avec un bouton en bas. Définissez la hauteur de la présentation sur "wrap_content" . Je ne l’ai pas essayé. Juste une idée
dans LinearLayout, ajoutez simplement Android:layout_weight="1"
à ListView
Voici ce qui a fonctionné pour moi ...
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);
}
Remarque: Le paramètre params.width = ... doit également être défini ...
L'exemple ci-dessus concerne l'utilisation de TableRow et ListView dans TableRow ...
envelopper le contenu dans une mise en page linéaire
en mode liste, ajoutez: Android: layout_weight = "1"
dans votre jeu de boutons hauteur fixe
<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>
Si vous souhaitez que le contenu situé sous la vue de liste descende au fur et à mesure que des éléments sont ajoutés à la liste, essayez cette solution:
Ajoutez un remplissage positif au bas de la vue et un remplissage négatif au haut du "pied de page". Cela fonctionnera dans une mise en page linéaire ou une mise en page relative.
<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"/>