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

안드로이드에서 ListView가 축소되지 않고 ScrollView 안에 온전히 표시되도록 하는 방법

ScrollView와 ListView는 둘 다 스크롤 기능을 내장한 뷰이기 때문에, ListView를 ScrollView 안에 그대로 배치하면 높이 계산에서 충돌이 발생해 리스트가 한두 항목만큼만 표시되거나 비정상적으로 축소되는 문제가 생깁니다.

이 예제에서는 ListView의 전체 높이를 직접 측정해 지정하는 방식으로, ScrollView 안에서도 ListView가 축소되지 않고 모든 항목이 온전히 보이도록 만드는 방법을 단계별로 소개합니다. 핵심 원리는 어댑터의 각 항목 높이를 하나씩 측정한 뒤, 항목 사이 구분선(divider) 높이까지 더한 값을 ListView의 높이로 설정하는 것입니다.

구현 단계

1단계 — 새 프로젝트 생성

Android Studio에서 File → New Project를 선택하고, 필요한 정보를 모두 입력하여 새 프로젝트를 생성합니다.

2단계 — 레이아웃 작성 (res/layout/activity_main.xml)

아래 코드를 res/layout/activity_main.xml 파일에 추가합니다. ScrollView 안에 LinearLayout을 배치하고, 그 안에 TextView와 ListView를 세로 방향으로 나란히 놓습니다.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
   xmlns:app="https://schemas.android.com/apk/res-auto"
   xmlns:tools="https://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">
   <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation ="vertical" >
      <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="19dp"
         android:text="hello_world" />
      <ListView
         android:id="@+id/listView"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent" />
   </LinearLayout>
</ScrollView>

3단계 — 메인 액티비티 작성 (src/MainActivity.java)

문자열 배열 데이터를 ArrayAdapter에 연결해 ListView에 설정한 후, 아래에서 만들 Helper 클래스의 getListViewSize() 메서드를 호출해 ListView의 높이를 재조정합니다.

package com.example.sample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
   private String listview_array[]={ "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN" };
   ListView myList;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      myList=(ListView) findViewById(R.id.listView);
      myList.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, listview_array));
      Helper.getListViewSize(myList);
   }
}

4단계 — Helper 클래스 작성 (src/Helper.java)

이 클래스가 해결책의 핵심입니다. 어댑터의 항목 수만큼 반복하면서 각 항목 뷰의 실제 높이를 measure()로 측정하고, 측정된 높이의 총합에 구분선 높이(항목 수 − 1개)를 더한 값을 ListView의 LayoutParams에 적용합니다. 덕분에 ListView가 화면 전체 높이를 차지해 ScrollView와 함께 정상적으로 스크롤됩니다.

package com.example.sample;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;
public class Helper {
   public static void getListViewSize(ListView myListView) {
      ListAdapter myListAdapter=myListView.getAdapter();
      if (myListAdapter==null) {
         //do nothing return null
         return;
      }
      //set listAdapter in loop for getting final size
      int totalHeight=0;
      for (int size=0; size < myListAdapter.getCount(); size++) {
         View listItem=myListAdapter.getView(size, null, myListView);
         listItem.measure(0, 0);
         totalHeight+=listItem.getMeasuredHeight();
      }
      //setting listview item in adapter
      ViewGroup.LayoutParams params=myListView.getLayoutParams();
      params.height=totalHeight + (myListView.getDividerHeight() * (myListAdapter.getCount() - 1));
      myListView.setLayoutParams(params);
      // print height of adapter on log
      Log.i("height of listItem:", String.valueOf(totalHeight));
   }
}

5단계 — 매니페스트 확인 (app/manifests/AndroidManifest.xml)

AndroidManifest.xml에는 별도의 권한 추가 없이 기본 설정 그대로 사용합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android" package="com.example.sample">
   <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(실행) 아이콘을 클릭하세요. 실행 대상으로 자신의 모바일 기기를 선택하면, 기기 화면에 아래와 같은 결과가 표시됩니다.

안드로이드에서 ListView가 축소되지 않고 ScrollView 안에 온전히 표시되도록 하는 방법

화면을 위아래로 스크롤하면 TextView와 ListView의 열 개 항목이 모두 잘리지 않고 함께 스크롤되는 것을 확인할 수 있습니다.

참고: 최신 안드로이드 개발에서는 ListView보다 RecyclerView 사용이 권장되며, 스크롤 영역 중첩이 필요한 경우 androidx의 NestedScrollView를 활용하면 더 유연하게 처리할 수 있습니다. 다만 기존 코드베이스를 유지보수할 때는 위 방법이 여전히 유용하게 쓰입니다.