Android에서 ListView의 높이 제한


92

아래에 버튼을 표시하고 싶습니다 ListView. 문제는 ListView확장되면 (항목 추가 ...) 버튼이 화면 밖으로 눌려진다는 것입니다.

LinearLayout가중치를 사용 하여 시도했지만 ( Android 에서 제안한대로 : View에 maxHeight가없는 이유는 무엇입니까? ) 가중치가 잘못되었거나 단순히 작동하지 않았습니다.

또한 어딘가에서 RelativeLayout. 은 ListView다음과 버튼 위에 설정됩니다 android:layout_abovePARAM.

이것의 문제는 나중에 버튼을 배치하는 방법을 모른다는 것입니다. 내가 찾은 예에서 아래의보기 ListView는를 사용하여 조정 android:layout_alignParentBottom되었지만 내 버튼이 화면 하단에 달라 붙는 것을 원하지 않습니다.

setHeight 메서드를 사용하고 필요한 공간을 계산하는 것 외에 다른 아이디어가 있습니까?


편집 : 유용한 답변이 많이 있습니다.

  • bigstone 및 user639183의 솔루션 은 거의 완벽하게 작동했습니다. 그러나 버튼 하단에 여백을 추가해야했습니다. 버튼이 여전히 화면에서 반쯤 밀려 나왔지만 중지되었습니다.

  • 상대 레이아웃에 대한 Adinia의 대답은 버튼을 화면 하단에 고정하려는 경우에만 좋습니다. 내가 의도 한 것은 아니지만 여전히 다른 사람들에게 유용 할 수 있습니다.

  • AngeloS의 솔루션은 내가 원하는 효과를 만들었 기 때문에 마지막에 선택한 솔루션이었습니다. 그러나 LinearLayout버튼 주변에 두 가지 사소한 변경을가했습니다 .

    • 내 레이아웃에있는 절대 값을 갖고 싶어하지 않았다 첫째, 나는 변화 android:layout_height="45px"wrap_content뿐만 아니라 잘 작동한다.

    • 둘째, vertical로만 지원되는 버튼이 수평 중앙에 위치하기를 원했기 때문에 LinearLayoutandroid : orientation = "horizontal"을 "vertical"로 변경했습니다.

    AngeloS는 또한 그의 초기 게시물 android:layout_weight="0.1"에서 LinearLayout주변의 매개 변수 ListView가 어떤 영향을 미쳤 는지 확실하지 않다고 말했습니다 . 나는 방금 시도했고 실제로 그렇습니다! 그렇지 않으면 버튼이 다시 화면 밖으로 밀려납니다.


이런 식으로 내부 상대 레이아웃이 화면보다 길어지고 한 단계는 android:layout_alignParentBottom="true". 그러나 명확하게 말하면 항목이 거의 없을 때 버튼이 ListView의 맨 아래에 붙어 있기를 원합니까? 그렇다면 Rich의 말을 참조하십시오.
bigstones 2011 년

네, 그게 제가 원하는 것입니다.
jellyfish

몇 년 후 ConstraintLayout 덕분에 이제 최대 높이를 갖게되었습니다. stackoverflow.com/questions/42694355/…
user1506104

답변:


55

나는이 정확한 문제가 있었고 그것을 해결하기 위해 각각 및 각각 LinearLayouts을 수용 하기 위해 두 개의 분리 를 만들었습니다 . 거기에서 두 가지를 모두 넣고 해당 컨테이너 를 . 나는 또한의 무게 설정 을 보관 에를 하지만 어떤 효과가 있을지 모릅니다. 여기에서 버튼이있는 하단 컨테이너의 높이를 원하는 높이로 설정할 수 있습니다.ListViewButtonLinear Layoutandroid:orientationverticalLinearLayoutListView0.1

이것이 내가 의미하는 바를 편집 하십시오.

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

위의 해결 방법은 화면 하단의 버튼을 수정합니다.


목록의 맨 아래에있는 버튼 플로트를하려면의 높이 변경 ListView01에를 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>


나는 그것을 <divHTML의 태그와 유사한 것으로 봅니다 . .. 그것은 단지 래퍼 이며이 솔루션은 확실히 작동합니다.
AngeloS 2011 년

그리고 오버 헤드에 관해서는, 당신이 상대 레이아웃으로하고있는 것과 크게 다르지 않습니다. .. 지금 당신은 하나의 외부 래퍼를 가지고 있고 다른 하나를 중첩하고 있습니다. 수직 선형 레이아웃에서 스택 효과를 만드는 두 개의 컨테이너에 버튼을 추가합니다. 이것이 작동하는 해결책이라고 충분히 강조 할 수는 없습니다.
AngeloS 2011 년

1
예! 이 작동합니다! 중요한 점은 첫 번째 솔루션과 두 번째 솔루션의 유일한 차이점은 linearlayout이 wrap_content에 필요하다는 것입니다. 따라서 imgur.com/c9L1Z 인 셉션 유형 설정으로 끝났습니다 . 이것을 발견 한 다른 사람에게 : 가중치는 중요하지만 어떤 가치도 가질 수 있습니다.
Sam

2
전혀 그런 모든 견해를 포장하기위한 필요 - 체크 아웃 스파클의 솔루션 @
리처드 르 Mesurier

버튼 레이아웃에 45px 또는 정확한 값을 입력해야합니까? 대신 wrap_content를 넣어야합니다
Mario Velasco 2014

65

코드에서이 문제를 해결하여 5 개 이상의 항목이있는 경우에만 listview의 높이를 설정했습니다.

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

최대 높이를 단일 항목 높이의 5.5 배로 설정 했으므로 사용자는 스크롤해야 할 작업이 있음을 확실히 알 수 있습니다. :)


1
좋은 대답입니다. 이 코드를 사용하여 내 항목의 높이를 발견하고 이제 목록의 크기를 설정하여 원하는 itens 수를 표시 할 수 있습니다. 감사.
Derzu

3
이것이 최고의 답변입니다. 5 줄의 코드로 문제를 해결할 수 있는데 왜 50 줄의 중첩 된 XML을 작성합니까?
Greg Ennis

@shaylh 감사합니다. 완벽하게 작동했습니다.
Anju

XML 솔루션을 멋지게 정리했지만 최종 제품에서이 아이디어를 사용하게되었습니다.
Richard Le Mesurier 2014-06-18

1
@JayR는 의견에 너무 늦게 결코
만자

21

마지막 편집 android:layout_above="@+id/butt1"에서 ListView 코드 도 추가하면 됩니다.

그리고 당신이 정말로 하나보다 더 사용할 필요가 없습니다 있음 (및 이전에 대한 답변을하려고 여기에 모든 사람을) 보여 RelativeLayout여기, 수정 된 코드 :

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

그리고 그 결과 , 어떤 임의의 목록을 사용하여 :
여기에 이미지 설명 입력


1
도와 주셔서 대단히 감사합니다.하지만 화면 하단에 고정 된 버튼은 제가 의도 한 것이 아닙니다 . ListView의 맨 아래에 있어야합니다.
jellyfish

사실, 이번에는 LinearLayouts가 당신이 원하는 것을위한 유일한 해결책이 될 것 같습니다; 나는 RelativeLayouts 서로 다른 조합을 시도했습니다, 아무도 정말 :( 일하지 ...하지만 난 당신이 대답을 발견 기뻐요.
Adinia

1
감사합니다! 그것은 완벽!
Guicara

6

를 사용 LinearLayout하여 ListViewButton에 높이를 설정하고 wrap_content에 weight = 1을 추가합니다 ListView. 원하는대로 작동합니다.
그리고 예, 설정 layout_gravity의를 Buttonbottom


6

AngeloS의 솔루션에서 영감을 얻은 중첩 컨테이너를 사용하지 않고이를 수행하는 방법을 찾았습니다.

나는 버튼 LinearLayout이있는 세로 방향 의 를 사용했습니다 ListView. 내가 설정 android:layout_weight="0.1"위해 ListView.

항상 목록의 맨 아래에 버튼 스틱을 가져옵니다. 그리고 목록이 커질 때 버튼이 화면에서 밀리지 않습니다.

<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
아니요, 그냥 시도했는데 버튼이 화면 하단에 유지되고 목록 하단에 유지되지 않습니다. :(
Adinia

@Adinia 이것은 적어도 4.4.3에서 완벽하게 작동합니다. 좋은 솔루션, Sparkle은 더 많은 표를 가져야합니다.
Richard Le Mesurier 2014-06-18

흠 .. 레이아웃에 다른 설정이 있습니까? 방금 4.4.3이 설치된 Nexus 4에서 다시 테스트했으며 버튼이 목록이 아닌 레이아웃의 맨 아래에 있으며 목록에 고정되지 않습니다.
Adinia 2014-06-18

2
@Richard Le Mesurier Indeed, android:layout_height="wrap_content" LinearLayout의 경우 솔루션에서와 마찬가지로 4.4.3에서 완벽하게 작동 할뿐만 아니라 Sparkle에서 언급하지 않았기 때문에 match_parent이전에 사용해 보았습니다 .
Adinia 2014-06-18

파이 작업도합니다. +1
Zubair Younas

5

RelativeLayout 버튼이 바닥에 너무 가깝게 유지되는 것을 원하지 않는 경우 여백을 추가 할 수 있습니다 (버튼을 패딩하면 9 패치 배경을 사용하고 자체 패딩을 설정하기 때문에 버튼이 깨질 수 있음).

a를 사용한 경우에도 동일 LinearLayout합니다. 원하는 것을 달성하는 방법은을 ListViewheight = 0 및 weight = 1로 설정하고 button height = wrap_content 및 weight = 0으로 설정하는 것입니다. (user639183이 말했듯이 둘 다 wrap_content로 설정하면 ListView의 높이가 제한되지 않습니다 ).


예, ListView의 높이를 제한합니다
ernazm 2011 년

@ user639183이 방금 시도했습니다. 맞습니다. 죄송합니다. 정말 확신했습니다.
bigstones 2011 년

제안 된대로 가중치를 변경했습니다 (이전에는 ListView weight = 2 및 button weight = 1이 있었는데 왜 이것이 작동하지 않았는지 궁금하십니까?) 효과가 매우 흥미 롭습니다. 이제 단추가 화면에서 반쯤 눌려졌습니다. 실제로 "android : layout_marginBottom"을 추가하여 원하는 위치에 그대로 둘 수 있습니다. 그러나 Maxims 접근 방식을 시도해보고 작동하는지 확인할 수도 있습니다.
jellyfish

@jellyfish : 모르겠습니다. @ user639183이 내 확신을 무너 뜨 렸습니다. 아이디어는 전체 높이가 두 뷰에서 공유된다는 것입니다. 그들이 얻는 주식의 양은 가중치에 따라 주어 지므로 1-0-> 모든 것이 첫 번째 (2-1은 두 번째 공간의 1/3을 제공합니다). 스크롤링 뷰에서 wrap_content를 설정하면 내용만큼 높아질 것이라고 생각했습니다. 그러나 .. 외부 레이아웃을 fill_parent로 설정 했습니까?
bigstones 2011 년

중첩 된 RelativeLayout (Maxim이 제안한대로)이 작동하지 않는 것은 정말 이상합니다. 내가 방금 뭔가를 놓친 느낌이 들었 기 때문에 위에 게시 할 수도 있습니다 ...
jellyfish

2

중첩 된 컨테이너를 사용하여이 작업을 수행 할 수 있습니다. 더 많은 공간을 차지하도록 두 번째 (내부) 컨테이너에 Button을 래핑하고 Button을 내부 컨테이너 상단에 정렬해야 할 수 있습니다.

다음과 같은 것이 가능합니다.

RelativeLayout

-- 목록보기

-RelativeLayout

---- 버튼

두 컨테이너에서 서로 다른 정렬 옵션을 사용하면이 작업을 수행 할 수 있습니다.


relativeLayout을 사용하는 것이 가장 좋은 해결책이라고 생각하지만 android:layout_marginTop="30dip" , 예를 들어 List와 Button 사이에 더 많은 공간을 원하는 경우 Button 과 같은 것을 사용할 수있을 때 중첩 컨테이너를 사용하는 이유를 알 수 없습니다 .
Adinia 2011 년

질문에서 OP는 ListView를 기준으로 버튼의 위치를 ​​엄격하게 지정하면 ListView가 충분히 커지면 화면에서 사라진다고 말했습니다. 이런 경우에는 중첩 된 컨테이너를 사용하기가 까다로워 야합니다
Rich

2

이것이 가장 깨끗한 방법입니다.

<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의 솔루션과 유사하지만 ListView를 래핑하는 선형 레이아웃이 필요하지 않습니다. 또한 LinearLayout에 비해 더 가벼운 FrameLayout을 사용하여 Button을 래핑 할 수 있습니다.


2

아이디어는 다음과 같은 매우 좋은 솔루션에 요약되어 있습니다.

둘 다 v4.4.3 이상에서 완벽하게 작동하는 것 같습니다.

나는 그것을 확인하고 각 방법을 확인하기 위해 여전히 테스트 코드를 작성하는 데 약간의 시간을 소비해야했다. 아래는 필요한 자체 포함 최소 테스트 코드입니다.


레이아웃은 중첩 된 레이아웃이 더 적기 때문에 Sparkle의 솔루션을 기반으로합니다. 또한 현재 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>

활동은 솔루션을 직접 테스트 할 수있는 상용구 코드를 제공합니다.

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

이것이 "커뮤니티 위키"이므로 자유롭게 추가하거나 개선하십시오.


1

하단에 버튼이있는 RelativeLayout을 사용해보십시오. 레이아웃의 높이를 "wrap_content"로 설정합니다. 나는 그것을 시도하지 않았습니다. 그냥 생각


나는 이것이 효과가 있다고 생각했지만 그렇지 않은 것 같습니다. 레이아웃은 높이가 match_parent로 설정된 것처럼 남은 공간을 모두 채 웁니다. 그래도 말이되지 않습니다.
jellyfish

1

LinearLayout에서 android:layout_weight="1"ListView에 추가하십시오.


0

다음은 나를 위해 일한 것입니다 ...

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


                }

참고 : params.width = ... 또한 설정해야합니다 ...

위의 예는 TableRow 내부에서 TableRow 및 ListView를 사용하는 경우입니다.


0

선형 레이아웃으로 콘텐츠 래핑

목록보기에서 추가 : android : layout_weight = "1"

버튼에 고정 높이 설정

<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

목록에 요소가 추가 될 때 목록보기 아래의 콘텐츠를 아래로 이동하려면 다음 해결 방법을 시도하십시오.

목록보기 하단에 양수 패딩을 추가하고 "바닥 글"상단에 음수 패딩을 추가합니다. 이것은 선형 레이아웃 또는 상대 레이아웃에서 작동합니다.

<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 속성이 없기 때문에 가장 좋은 방법은 ListView의 높이를 설정 값으로 설정하거나 wrap_content.


-2

ListView를 ScrollView 안에 넣어이 문제를 해결했습니다. Lint는 그것을 좋아하지 않았지만 minHeight를 추가하고 fillViewport를 true로 설정하면 좋은 결과를 얻을 수 있습니다.

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

나는이 접근 방식을 시도했지만 목록보기의 크기를 제한하더라도 목록보기를 스크롤 할 수 없으므로 어색합니다. 그 이유를 아십니까?
Eduardo

7
ListView를 ScrollView 안에 넣지 마십시오!
jenzz 2011

예, ListView를 ScrollView 안에 넣지 마십시오. 그러나이 그것을 가능 ...입니다 "해킹" stackoverflow.com/a/14577399/1255990
레오나르도 카르도소
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.