Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Kotlin으로 안드로이드에서 ListView를 ScrollView에 넣어도 축소되지 않게 하는 방법


안드로이드 앱을 개발하다 보면 ScrollView 안에 ListView를 배치해야 하는 경우가 종종 있습니다. 그런데 ScrollView는 자식 뷰의 높이를 제한 없이(unspecified) 측정하기 때문에, ListView가 자신의 실제 높이를 계산하지 못하고 첫 번째 항목 정도의 높이로 축소되어 버리는 문제가 자주 발생합니다.

이 글에서는 Kotlin을 사용해 ListView가 ScrollView 안에서 축소되지 않고 모든 항목을 온전히 표시하도록 만드는 방법을 단계별로 알아보겠습니다.

1단계 — 새 프로젝트 생성

Android Studio에서 File → New Project 메뉴로 이동한 뒤, 프로젝트 생성에 필요한 정보를 모두 입력하고 새 프로젝트를 만듭니다.

2단계 — activity_main.xml 작성

res/layout/activity_main.xml 파일에 아래 코드를 추가합니다.

예제

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="4dp"
    tools:context=".MainActivity">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
<ListView
    android:id="@+id/listView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />
</LinearLayout>
</ScrollView>

3단계 — MainActivity.kt 작성

src/MainActivity.kt 파일에 다음 코드를 추가합니다. ArrayAdapter로 문자열 배열을 ListView에 연결한 뒤, 곧 만들 ListHelper의 getListViewSize() 함수를 호출하는 것이 핵심입니다.

import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.ListView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
    private val listViewArray = arrayOf(
        "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE",
        "TEN", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen"
    )
    lateinit var list: ListView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "KotlinApp";
        list = findViewById(R.id.listView)
        list.adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listViewArray)
        ListHelper.getListViewSize(list)
    }
}

4단계 — ListHelper.kt 유틸리티 클래스 작성

새 Kotlin 클래스 ListHelper.kt를 만들고 아래 코드를 추가합니다. 이 클래스가 이 예제의 핵심입니다. 어댑터의 각 항목 뷰를 하나씩 가져와 measure()로 높이를 측정한 후, 항목 높이의 합에 구분선(divider) 높이를 더한 값을 ListView의 layoutParams.height에 지정함으로써 ListView가 전체 크기를 갖도록 강제합니다.

import android.util.Log
import android.widget.ListAdapter
import android.widget.ListView
object ListHelper {
    fun getListViewSize(myListView: ListView) {
        val myListAdapter: ListAdapter = myListView.adapter
            ?: //do nothing return null
            return
        //set listAdapter in loop for getting final size
        var totalHeight = 0
        for (size in 0 until myListAdapter.count) {
            val listItem = myListAdapter.getView(size, null, myListView)
            listItem.measure(0, 0)
            totalHeight += listItem.measuredHeight
        }
        //setting listView item in adapter
        val params = myListView.layoutParams
        params.height =
            totalHeight + myListView.dividerHeight * (myListAdapter.count - 1)
        myListView.layoutParams = params
        // print height of adapter on log
        Log.i("height of listItem:", totalHeight.toString())
    }
}

5단계 — AndroidManifest.xml 작성

androidManifest.xml에 아래 코드를 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.q11">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

앱 실행 및 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 안드로이드 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 아이콘Kotlin으로 안드로이드에서 ListView를 ScrollView에 넣어도 축소되지 않게 하는 방법을 클릭하세요. 실행 옵션에서 본인의 모바일 기기를 선택하면, 기기 화면에 ListView의 모든 항목이 축소되지 않은 채 정상적으로 표시되는 것을 확인할 수 있습니다.

Kotlin으로 안드로이드에서 ListView를 ScrollView에 넣어도 축소되지 않게 하는 방법

참고: 더 나은 대안

ListView를 ScrollView에 넣는 구조는 항목 뷰를 반복적으로 측정해야 하므로 성능 면에서 권장되지 않습니다. 최신 안드로이드 개발에서는 NestedScrollView + RecyclerView 조합을 사용하거나, 목록 하나만 필요하다면 RecyclerView(또는 ListView)가 스크롤을 직접 처리하도록 하는 것이 좋습니다. 다만 레거시 코드 유지보수 등 부득이한 상황에서는 위의 ListHelper 방식이 여전히 유용하게 활용될 수 있습니다.