[Android Studio] / [안드로이드 스튜디오]
ListView Adapter return always 0 (index) / 리스트뷰에 한 개의 아이템만 나올 때
Adapter에 두개의 객체를 담아 보여주는 짓을 마무리 하는데 ListView에 아이템이 한개만 노출되는 현상을 목격...
아무리 로그를 찍어도 왜 한개만 노출되는지 모르겠다..안 보여줄거면 다 안나오던가... 왜 1개만이냐고...
어댑터에서 문제가 생긴 것 같아서 어댑터에 getView() 메소드 로그를 찍어봤는데
12-05 14:14:48.870 8419-8419/com.m3s.skylark E/DashBoardAdapter: getView ( position ) : 0
어댑터 자체에서 한 번만 돌았다는 사실을 알게 됐고 로직 문제가 아니라 판단하여 혹시 리스트뷰의 attribute 때문인가!?
그렇게 구글링 하던 중에 이유를 알게 된다.
ScrollView 안에 ListView를 쓰지 마라!
ScrollView 안에서는 ListView의 높이를 파악할 수 없기 때문에 생겨나는 문제이다.
ListView 자체도 Scroll 기능을 포함하고 있으니 이 속성끼리 부딪혀 생겨나는 모양이다. 첫 아이템이 세팅되고 스크롤이 내려가지 못해 다음 아이템 자체를 읽어오지 못하는 것..
따라서 해결하려면 ListView의 높이를 재측정하여 파라미터로 ScrollView에 알려줘야 한다.
일단 스크롤 뷰에 ViewPort속성을 True로 주고
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fillViewport="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
.....
<ListView
android:id="@+id/lvGroup"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</ScrollView>
java class 내에서 리스트 뷰의 높이를 다시 세팅해주는 함수를 만든다.
public static void setListViewHeight(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 자체의 height)에 아이템 수만큼 +
listView.setLayoutParams(params); //리스트뷰에 파라미터 세팅
listView.requestLayout();
}
그리고 어댑터를 세팅한 다음에 바로 이 함수를 호출해주면 끗 -
'Satisfaction' 님의 블로그에 따르면 ListView자체에 padding 옵션을 준 경우, 저 함수를 불러줘도 height가 모자란 상태로 조정된다고 한다.
저 함수는 View의 높이 자체만 계산하기 때문에 외부적 요소에 관해서는 알아채지 못하기 때문이다.
따라서 RecyclerVIew를 사용하는 방법을 추천한다
<참고자료>
medium.com/@sinyakinv/your-solution-doesnt-solve-problem-fully-e5f97cad2a12