Android'de ListView yüksekliğini sınırla


92

Altında bir düğme göstermek istiyorum ListView . Sorun, ListViewuzatılırsa (öğeler eklenir ...), düğme ekrandan dışarı itilir.

Denedim LinearLayoutAğırlıklı ( Android'de önerildiği gibi : Neden bir Görünüm için maxHeight yok? ), Ama ya ağırlıkları yanlış anladım ya da işe yaramadı.

Ayrıca, bir yerde kullanmak için ipucu buldum RelativeLayout . Daha ListViewsonra, android:layout_aboveparam ile düğmenin üstüne ayarlanır .

Bununla ilgili sorun, düğmeyi daha sonra nasıl konumlandıracağımı bilmemem. Bulduğum örnekte, aşağıdaki GörünümListView kullanılarak ayarlandı android:layout_alignParentBottom, ancak düğmemin ekranın altına yapışmasını istemiyorum.

SetHeight yöntemini kullanmak ve gerekli alanın hesaplanması dışında herhangi bir fikir var mı?


Düzenleme: Çok sayıda faydalı cevabım var.

  • bigstone & user639183'ün çözümü neredeyse mükemmel çalıştı. Ancak, yine de ekranın yarısına kadar itileceği için (ancak daha sonra durdurulacağı için) düğmenin altına fazladan bir dolgu / kenar boşluğu eklemem gerekiyor

  • Adinia'nın göreceli düzen ile yanıtı, düğmenin ekranın altına sabitlenmesini istiyorsanız yeterlidir. Amaçladığım şey bu değil ama yine de başkaları için faydalı olabilir.

  • AngeloS'un çözümü, istediğim efektleri yarattığı için sonunda seçtiğim çözümdü. Ancak, LinearLayoutdüğmenin çevresinde iki küçük değişiklik yaptım :

    • Benim düzeninde herhangi mutlak değerlere sahip istemiyordu olarak Birincisi, ben değiştirdi android:layout_height="45px"için wrap_contentde gayet güzel çalışıyor, hangi.

    • İkincisi, düğmenin yatay olarak ortalanmasını istediğim için, bu sadece dikey olarak destekleniyor LinearLayout, android: orientation = "horizontal" i "dikey" olarak değiştirdim.

    AngeloS ayrıca ilk gönderisinde android:layout_weight="0.1", LinearLayoutetrafındaki paramın ListViewherhangi bir etkisi olup olmadığından emin olmadığını belirtti ; Sadece denedim ve gerçekten yapıyor! Olmazsa düğme ekrandan tekrar itilir.


bu şekilde iç göreceli düzen ekrandan daha uzun büyüyor, bir adım eklenebilir android:layout_alignParentBottom="true". Ancak açık olmak gerekirse, birkaç öğe olduğunda düğmenin ListView'un altına bağlı kalmasını istiyor musunuz? Cevabınız evetse, Rich'in ne dediğine bakın.
bigstones

evet, istediğim bu.
denizanası

yıllar sonra, ConstraintLayout sayesinde artık maksimum yüksekliğe sahibiz: stackoverflow.com/questions/42694355/…
user1506104

Yanıtlar:


55

Tam olarak bu sorunu yaşadım ve çözmek LinearLayoutsiçin ListViewve Buttonsırasıyla ve barındırmak için iki ayrı oluşturdum . Oradan başka hem koymak Linear Layoutve konteyner olduğunu sette android:orientationiçin vertical. Ben de ağırlığını ayarlamak LinearLayoutev sahipliği ListViewiçin 0.1ancak herhangi bir etkisi olup olmadığını bilmiyorum. Oradan, alt kabın (düğmenizin bulunduğu) yüksekliğini istediğiniz yüksekliğe ayarlayabilirsiniz.

DÜZENLE Demek istediğim bu:

<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:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="0.1"
    android:orientation="horizontal">

    <ListView
        android:id="@+id/ListView01"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:dividerHeight="2px"></ListView>
</LinearLayout>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="45px"
    android:background="@drawable/drawable"
    android:orientation="horizontal">

    <Button
        android:id="@+id/moreButton"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentRight="true"
        android:background="@drawable/btn_more2"
        android:paddingRight="20px" />

</LinearLayout>

Yukarıdaki çözüm, düğmeyi ekranın alt kısmına sabitleyecektir.


Düğmenin listenin en altında kaymasını sağlamak için, yüksekliğini şu şekilde ListView01değiştirin 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:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="0.1"
    android:orientation="horizontal">

    <ListView
        android:id="@+id/ListView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:dividerHeight="2px"></ListView>
</LinearLayout>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="45px"
    android:background="@drawable/drawable"
    android:orientation="horizontal">

    <Button
        android:id="@+id/moreButton"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentRight="true"
        android:background="@drawable/btn_more2"
        android:paddingRight="20px" />
</LinearLayout>


Bunu HTML'deki <divetiketlere benzer bir şey olarak görüyorum .. sadece bir sarmalayıcı ve bu çözüm kesinlikle işe yarıyor.
AngeloS

Ve genel giderle ilgili olarak, bu, göreceli düzenlerde yaptığınızdan çok da farklı değil .. Şu anda bir dış sarmalayıcınız var ve bir başkasını iç içe geçiriyorsunuz .. sadece bir tane daha iç içe geçirmenizi ve liste görünümünü bölmenizi öneriyorum ve düğme, dikey doğrusal düzende bir yığın efekti oluşturan iki kapta. Bunun çalışan bir çözüm olduğunu yeterince vurgulayamıyorum.
AngeloS

1
EVET! bu çalışıyor! Dikkat edilmesi gereken önemli, ilk ve 2. çözümünüz arasındaki tek fark, linearlayout'un wrap_content'e ihtiyaç duymasıdır, bu yüzden bir başlangıç ​​türü kurulumuyla sonuçlandım: imgur.com/c9L1Z . Bunu bulan başka birine: ağırlıklandırma önemlidir, ancak herhangi bir değer alabilir.
Sam

2
tüm görüşleri böyle sarmalamaya gerek yok - @ Sparkle'ın çözümüne göz
Richard Le Mesurier

Düğme düzeni için 45px mi yoksa tam bir değer mi koymak gerekiyor? Bunun yerine wrap_content koymam gerekiyor
Mario Velasco

65

Bu sorunu kodda çözdüm, liste görünümünün yüksekliğini yalnızca içinde 5'ten fazla öğe varsa ayarladım:

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);
}

Maksimum yüksekliği tek bir öğenin yüksekliğinin 5,5 katı olarak ayarladığıma dikkat edin, böylece kullanıcı yapılacak bazı kaydırma işlemlerinin olduğundan emin olacaktır! :)


1
Güzel cevap. Bu kodla öğemin yüksekliğini keşfediyorum ve şimdi listemin boyutunu kaç tane öğe istediğimi gösterecek şekilde ayarlayabilirim. Teşekkürler.
Derzu

3
Bu en iyi cevap. Problemi 5 satır kodla çözebilecekken neden 50 satır iç içe XML yazasınız ki?
Greg Ennis

Teşekkür ederim @shaylh. Mükemmel çalıştı.
Anju

XML çözümlerini güzelce temizlememe rağmen, bu fikri nihai ürünümde kullanmaya devam ettim.
Richard Le Mesurier

1
@JayR yorum yapmak için asla geç değildir
Manza

21

Son düzenlemenizde, android:layout_above="@+id/butt1"ListView kodunuzu da eklemeniz yeterlidir.

Ve size (ve daha önce bir cevabı deneyen herkese) gerçekten birden fazla kullanmanıza gerek olmadığını göstermek için RelativeLayout, işte düzeltilmiş kodunuz :

   <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>

ve rastgele bir liste kullanarak sonuç :
görüntü açıklamasını buraya girin


1
Yardımınız için çok çok teşekkür ederim, ancak düğmenin ekranın alt kısmına sabitlenmesi benim niyetimde değildi . ListView’un altında olması gerekiyordu.
denizanası

Aslında, bu sefer LinearLayouts istediğiniz şey için tek çözüm olabilir gibi görünüyor; RelativeLayouts ile farklı kombinasyonlar denedim ve hiçbiri gerçekten işe yaramadı :( ... Ama cevabını
bulmana

1
Teşekkür ederim! Mükemmel!
Guicara

6

Kullanılması LinearLayoutsenin yüksekliğini ayarlamak ListViewve Buttonkarşı wrap_contentve bir ağırlık = 1 ekleyin ListView. Bu istediğiniz gibi çalışmalıdır.
Ve evet, set layout_gravityarasında Buttonhiçbottom


6

AngeloS'un çözümünden esinlenerek, bunu iç içe geçmiş kapsayıcılar kullanmadan yapmanın bir yolunu buldum.

Bir kullanılan LinearLayoutbir olan bir dikey doğrultuda olan ListViewve bir düğme. Ben set android:layout_weight="0.1"için ListView.

Her zaman düğme çubuğunu listenin altına almayı başarır. Ve liste büyüdüğünde düğme ekrandan itilmiyor.

<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"
    />

2
Hayır, sadece denedim ve düğme ekranın altında kalıyor, listenin altında kalmıyor. :(
Adinia

@Adinia Bu, en azından 4.4.3'te mükemmel çalışıyor. Güzel çözüm Sparkle, daha çok oy almalı.
Richard Le Mesurier

Humm..belki düzeninizde başka ayarlarınız var? 4.4.3 ile bir Nexus 4 üzerinde tekrar test ettim ve düğme listenin değil, düzenin altında kalıyor, listeye yapışmıyor.
Adinia

2
@Richard Le Mesurier Gerçekten de, android:layout_height="wrap_content" LinearLayout ile sizin çözümünüzde olduğu gibi mükemmel çalışıyor ve sadece 4.4.3'te değil, Sparkle bundan bahsetmediği için daha match_parentönce denedim .
Adinia

Pie üzerinde de çalışıyor. +1
Zubair Younas

5

RelativeLayout bir çözümdür, düğmenin dibe çok yakın kalmasını istemiyorsanız, kenar boşlukları ekleyebilirsiniz (bir düğmeyi doldurmak onu kırar çünkü 9 yamalı bir arka plan kullanır ve kendi dolgusunu ayarlar).

Eğer a kullansaydınız da aynı olurdu LinearLayout: İstediğinizi elde etmenin yolu, ListViewbir yükseklik = 0 ve ağırlık = 1 ve düğme için yükseklik = wrap_content ve ağırlık = 0 olarak ayarlamaktır. (user639183'ün dediği gibi her ikisinin de wrap_content olarak ayarlanması, ListViewyüksekliğini sınırlamaz ).


Evet, ListViewboyunu sınırlayacak
ernazm

@ user639183 az önce denedim, haklısın üzgünüm, bundan çok emindim.
bigstones

Ağırlığı önerildiği gibi değiştirdim (daha önce ListView ağırlığı = 2 ve düğme ağırlığı = 1 vardı, bunun neden işe yaramadığını merak ettim) Etkisi çok ilginç: düğme artık ekranın yarısına kadar itiliyor. Aslında, biraz "android: layout_marginBottom" ekleyerek istediğim yerde kalmasını sağlayabilirim. Bununla birlikte, Maxims yaklaşımını da deneyebilir ve bunun da işe yarayıp yaramadığını görebilirim.
denizanası

@jellyfish: Bilmiyorum, kesinliklerim @ user639183 tarafından yıkıldı. Buradaki fikir, tüm yüksekliğin iki görüş tarafından paylaşılacağıdır. Alacakları hisse miktarı ağırlıklarına göre verilir, yani 1-0 -> her şey birinciye (2-1, ikinciye 1/3 boşluk verir). Kaydırma görünümünde wrap_content ayarlamanın, içeriği kadar yüksek yapacağını düşündüm. Ancak .. dış düzeni fill_parent olarak ayarladınız mı?
bigstones

Yuvalanmış bir RelativeLayout'un (Maxim'in önerdiği gibi) çalışmaması gerçekten garip. Bir şeyi kaçırdığımı hissettiğim için yukarıya
koyabilirim

2

Bu işlemi büyük olasılıkla iç içe geçmiş kapsayıcılar kullanarak yapabilirsiniz. Daha fazla yer kaplaması için Düğmeyi ikinci (iç) bir kaba sarmanız ve Düğmeyi iç kabın üstüne hizalamanız gerekebilir.

Bunun gibi olası bir şey:

Göreli Düzen

-- Liste görünümü

- Göreli Düzen

---- Buton

İki kaptaki farklı hizalama seçeneklerini kullanarak, bunu çalıştırabilmelisiniz.


Bence bir relativeLayout kullanmanın en iyi çözüm olduğunu düşünüyorum, ancak android:layout_marginTop="30dip" örneğin List ve Button arasında daha fazla boşluk istiyorsanız Button gibi bir şey kullanabiliyorsanız, neden yuvalanmış kaplar kullandığınızı gerçekten anlayamıyorum .
Adinia

soruda OP, listView'e göre düğmenin konumlandırmasını kesin olarak yaparsa, ListView yeterince büyüdükten sonra ekrandan kaybolacağını söyledi. Bu tür durumlarda iç içe geçmiş kapsayıcılarla
Zengin

2

Bunu yapmanın en temiz yolu şudur:

<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>

Angelos'un çözümüne benzer, ancak ListView'ı tamamlayan doğrusal düzene ihtiyacınız yok. Ayrıca, Button'ı sarmak için LinearLayout'a kıyasla daha hafif olan bir FrameLayout kullanabilirsiniz.


2

Fikir, çok iyi çözümlerde şu şekilde özetlenmiştir:

İkisi de en azından v4.4.3'te mükemmel çalışıyor gibi görünüyor.

Yine de kontrol etmek ve her yöntemi onaylamak için test kodunu yazmak için biraz zaman harcamak zorunda kaldım. Aşağıda bağımsız, minimum test kodu gereklidir.


Düzen, daha az iç içe geçmiş düzen içerdiğinden Sparkle'ın çözümüne dayanmaktadır. Ayrıca, mevcut LINT kontrollerini yansıtacak şekilde güncellenmiştir.

<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>

Etkinlik, çözümü kendiniz için test etmek için standart kod sağlar.

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);
            }
        });
    }
}

Bu "topluluk wiki" olduğu için eklemekten veya geliştirmekten çekinmeyin.


1

Alttaki düğme ile RelativeLayout'u kullanmayı deneyin. Düzenin yüksekliğini "wrap_content" olarak ayarlayın. Ben denemedim. Sadece fikir


Bunun gerçekten işe yaraması gerektiğini düşündüm, ama öyle görünmüyor. Düzen, yükseklik match_parent olarak ayarlanmış gibi, kalan tüm boşluğu doldurur. Yine de mantıklı değil.
denizanası

1

LinearLayout'ta, android:layout_weight="1"ListView'a eklemeniz yeterli


0

Benim için işe yarayan şey şu ...

 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);


                }

Not: params.width = ... Ayrıca ayarlanması gerekir ...

Yukarıdaki örnek, TableRow içinde TableRow ve ListView kullandığınızda ...


0

içeriği doğrusal düzende sar

Liste Görünümünde şunu ekleyin: android: layout_weight = "1"

Düğmenizde sabit yükseklik ayarlayın

<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>

0

Listeye öğeler eklendikçe liste görünümünün altındaki içeriğin aşağı hareket etmesini istiyorsanız, şu çözümü deneyin:

Liste görünümünün altına pozitif dolgu ve "altbilgi" nin üstüne negatif dolgu ekleyin. Bu, doğrusal bir düzende veya göreceli bir düzende çalışacaktır.

<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"/>

-1

MaxHeight özelliği olmadığı için, en iyi bahsiniz ya ListView yüksekliğini belirli bir değere ayarlamak ya da kullanmaktır wrap_content.


-2

ListView'ı bir ScrollView içine koyarak bunu çözdüm. Lint bundan hoşlanmadı, ancak bir minHeight ekleyerek ve fillViewport'u true olarak ayarlayarak güzel bir sonuç aldım.

    <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>        

Bu yaklaşımı denedim, liste görünümünün boyutunu sınırlasanız bile, garip olan liste görünümünü kaydırmama izin vermiyor. Neden biliyor musun?
Eduardo

7
Bir ScrollView içine ASLA ListView koymayın!
jenzz

Evet, bir ScrollView içine asla bir ListView koymayın. Ama bu "hack" ile mümkün ... stackoverflow.com/a/14577399/1255990
Leonardo Cardoso
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.