만족

[Android Studio] ScrollView/ListView height 불일치 문제 본문

[Android Studio] ScrollView/ListView height 불일치 문제

FrontEnd/Android Satisfaction 2019. 7. 11. 04:40

ListView는 꽤 옛날에 나온 놈이라 호환성이 그렇게 좋지 못하다.

 

제목에서도 언급했듯이 가장 많이 문제를 일으키는 경우는 ScrollView 내부에 ListView가 존재할 때 이다.

이 경우 ListView의 전체 높이가 ListView의 하나의 목록의 높이로 잡혀서 상당히 괴이한 모양의 컴포넌트를 만들어낸다.

 

대안은 두 가지가 있다.

 

첫 번째는 ListView를 버리는 방법이다. 위의 문제를 해결하기 위해서, 그리고 성능 향상을 위해서 ListView대신 RecyclerView를 이용하는 방법이다. 이 방법은 구글에 Android RecyclerView example만 쳐도 수백개의 예제가 나오므로 설명은 생략한다.

이 방법의 단점은 매우 번거롭다는 것이다. Adapter를 갈아엎는 수준으로 만들어야 하는 데다가, 코드 길이 자체도 기존의 BaseAdapter에 비하면 매우 길다.

 

두 번째는 위의 구조에서, ScrollView에 fillViewport= "true"옵션을 주고, ListView에 setAdapter 한 다음

그 ListView에 대해서, 


public static void setListViewHeightBasedOnChildren(@NonNull ListView listView) {
  ListAdapter listAdapter = listView.getAdapter();

  int totalHeight = 0;
  for (int i = 0; i < listAdapter.getCount(); i++) {
    View listItem = listAdapter.getView(i, null, listView);
    listItem.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    totalHeight += listItem.getMeasuredHeight();
  }

  ViewGroup.LayoutParams params = listView.getLayoutParams();
  params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
  listView.setLayoutParams(params);
  listView.requestLayout();
}

 

를 호출하면 정상적으로 height가 재조정된다.

 

물론 이것으로도 완벽하게 해결되지 않는다.

 

예를 들면 ListView자체에 padding 옵션을 준 경우, 저 함수를 불러줘도 height가 모자란 상태로 조정된다.

저 함수는 View의 높이 자체만 계산하기 때문에 외부적 요소에 관해서는 알아채지 못하기 때문이다.

이 경우엔 귀찮더라도 해당 adapter에서 사용하는 xml로 가서 그 리스트 요소 스타일에 padding을 주어야 한다.

 

또한 높이값에 wrap_content를 주었을 경우, 그 높이가 가변적인 뷰 라면

(예를 들어서 텍스트의 길이에 따라 1줄이 되거나 2줄이 되거나 하는 경우)

해결하기가 매우 까다로워지게 된다.

 

웬만하면 조금 복잡하긴 해도 RecyclerView에 익숙해지는게 더 좋을 것이다.



Comments