Layout Android com ListView e botões

101

Tudo bem, esse layout específico está apenas me irritando. E não consigo encontrar uma maneira de ter um listView, com uma fileira de botões na parte inferior para que o listview não se estenda por cima dos botões e, portanto, os botões estão sempre ajustados para a parte inferior da tela. Aqui está o que eu quero:

link morto do ImageShack removido

Parece que deveria ser tão fácil, mas tudo o que tentei falhou. Qualquer ajuda?

Este é meu código atual:

    RelativeLayout container = new RelativeLayout(this);
    container.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));

    //** Add LinearLayout with button(s)

    LinearLayout buttons = new LinearLayout(this);

    RelativeLayout.LayoutParams bottomNavParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    bottomNavParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    bottomNavParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
    buttons.setLayoutParams(bottomNavParams);


    ImageButton newLayer = new ImageButton(this);
    newLayer.setImageResource(R.drawable.newlayer);
    newLayer.setLayoutParams(new LinearLayout.LayoutParams(45, LayoutParams.FILL_PARENT));
    buttons.addView(newLayer);

    container.addView(buttons);

    //** Add ListView

    layerview = new ListView(this);

    RelativeLayout.LayoutParams listParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    listParams.addRule(RelativeLayout.ABOVE, buttons.getId());

    layerview.setLayoutParams(listParams);

    container.addView(layerview);
Kleptine
fonte
Boa pergunta, muitos desenvolvedores vão ficar presos nisso.
Signcodeindie
Felizmente, o designer do Android é muito fofo. Portanto, ao criar um layout / UI, tente usar o Designer / XML. Especialmente para este cenário, uma vez que é apenas um conjunto de botões e um ListView.
Subby

Respostas:

137

Eu acho que isto é o que você está procurando.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">

    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:id="@+id/testbutton"
        android:text="@string/hello" android:layout_alignParentBottom="true" />

    <ListView android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:id="@+id/list"
        android:layout_alignParentTop="true" android:layout_above="@id/testbutton" />

</RelativeLayout>
Lars
fonte
É o que basicamente tenho usado, embora esteja escrevendo o layout em Java. O listView ainda se estende aos botões.
Kleptine
1
A única coisa que estou mudando é que estou adicionando um relativeLayout ao redor do ListView porque não posso chamar addRule (RelativeLayout.ABOVE) em um ListView.
Kleptine
2
Este código deve funcionar bem. android:layout_above="@id/testbutton"manterá o ListViewacima do Button.
CommonsWare
Quando eu uso isso, eu obtenho a lista para parar acima do botão e, em seguida, começo a rolar internamente.
lars
7
Você também não invoca addRule(RelativeLayout.ABOVE)um RelativeLayout. Você chama em a RelativeLayout.LayoutParams. Você então adiciona o ListViewao RelativeLayout, fornecendo-o RelativeLayout.LayoutParams. Considere mudar para XML e aumentá-lo, para manutenção de longo prazo.
CommonsWare
57

Eu tive o mesmo problema por muito tempo.

A solução para manter o ListView acima dos botões, mas evitando que ele os cubra quando a lista for longa, é definir android: layout_weight = "1.0" no ListView. Deixe o layout_weight nos botões não definido para que eles permaneçam em seu tamanho natural, caso contrário, os botões serão redimensionados. Isso funciona com LinearLayout.

Há um exemplo no Android ApiDemos: ApiDemos / res / layout / linear_layout_9.xml

David Ingram
fonte
me poupe mais algumas horas. Não conseguia entender por que os botões nunca apareceram. :)
frostymarvelous
Eu não entendo completamente porque isso funciona, mas funciona :)
Bevor
20

Eu estava apenas procurando uma resposta para essa pergunta e esse foi um dos primeiros resultados. Sinto como se todas as respostas, incluindo aquela que é atualmente escolhida como a "melhor resposta", não abordassem o problema que está sendo perguntado. O problema que está sendo declarado é que há uma sobreposição dos dois componentes Buttone ListViewem que o ListView está ocupando a tela inteira, e o botão está visualmente flutuando acima (na frente) do ListView (bloqueando a visualização / acesso do último item noListView )

Com base nas respostas que vi aqui e em outros fóruns, finalmente cheguei a uma conclusão sobre como resolver isso.

Originalmente, eu tinha:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#FF394952">

  <ListView
    android:id="@+id/game_list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    />

  <LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    style="@android:style/ButtonBar">

    <Button
      android:id="@+id/new_game"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/new_game"
      android:textColor="#FFFFFFFF"
      android:background="@drawable/button_background" />
  </LinearLayout>

</RelativeLayout>

Observe o uso de RelativeLayout como o nó raiz.

Esta é a versão final de trabalho na qual o botão não se sobrepõe a ListView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#FF394952">

  <ListView
    android:id="@+id/game_list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_weight="1.0" />

  <LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    style="@android:style/ButtonBar">

    <Button
      android:id="@+id/new_game"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/new_game"
      android:textColor="#FFFFFFFF"
      android:background="@drawable/button_background" />
  </LinearLayout>

</LinearLayout>

Existem apenas duas diferenças. Primeiro, mudei para usar um LinearLayout. Isso vai ajudar com a próxima parte, que foi adicionarandroid:layout_weight ao meuListView

Eu espero que isso ajude.

Dallas
fonte
Isso resolve, mas quem diria !? Quando você dá android:layout_alignParentBottomdentro de um LinearLayoutpai, o ADT diz "Parâmetro de layout inválido em um LinearLayout: layout_alignParentBottom"!
Aswin Kumar
8

A melhor maneira é um layout relativo que define os botões abaixo da lista. Neste exemplo, os botões também estão em um layout linear porque é mais fácil colocá-los lado a lado em um tamanho igual.

<RelativeLayout android:id="@+id/RelativeLayout01" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent">

<ListView android:id="@+id/ListView01" 
android:layout_alignParentTop="true"
android:layout_width="fill_parent" 
android:layout_height="fill_parent">
</ListView>

<LinearLayout android:id="@+id/LinearLayout01" 
android:layout_below="@+id/ListView01" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:layout_alignParentBottom="true">
<Button android:id="@+id/ButtonJoin" 
android:text="Join"
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_alignParentBottom="true">
</Button>
<Button android:id="@+id/ButtonJoin" 
android:layout_alignRight="@id/ButtonCancel" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel"
android:layout_alignParentBottom="true">
</Button>
</LinearLayout>

</RelativeLayout>
Patrick Kafka
fonte
O problema é que ele se estende por cima dos botões na parte inferior se a exibição da lista for muito longa. Não consigo descobrir como fazê-lo parar acima dos botões.
Kleptine
2
Se você estiver usando (eu acho que 1.5, talvez até 1.6) você DEVE ter os botões ANTES do ListView ao usar as regras RelativeLayout - caso contrário, o layout não reconhece os botões ainda porque os lê em ordem, é por isso que seu ListView estende por eles.
Tim H
Isso não funciona para mim. Como Tim H disse, para mim devo colocar o ListView após o LinearLayout e então fazer o ListView layout_above, como a resposta de repoc acima.
Nemi
isso não funcionará, o botão não estará na tela e não rolará
Vaibhav Mishra
1

Eu sei que este post é um pouco antigo, mas, para responder à pergunta do autor original, o motivo pelo qual o código não funcionou foi buttons.getId () retorna -1. Se você vai fazer isso, você precisa definir fazer algo como call buttons.setId (10). Se você fizer isso, o código funcionará perfeitamente.

Doo Dah
fonte
0

isso deve funcionar. para ter botões acima do listview também, coloque os botões dentro de outro layout linear.

<LinearLayout> main container // vertical

<LinearLayout> scrollview must be contained in a linear layout //vertical - height to fill parent

    <ScrollView> set the height of this to fill parent

        <ListView> will be contained in the scrollview
        </ListView>

    </ScrollView>

</LinearLayout>

<LinearLayout> //horizontal - height to wrap content

<Button>

</Button>

</LinearLayout>

</LinearLayout>
Rhys
fonte
0

a solução mais fácil seria criar dois layouts lineares, um com o botão e outro com a exibição de lista (envolver o conteúdo na altura do botão e combinar o pai na altura do layout da lista). em seguida, faça apenas uma visualização de rolagem sobre o layout com a visualização de lista e o layout dos botões será ignorado. espero que ajude, desculpe, eu não tive vontade de escrever o código.

Pete
fonte