ภาพรวม
ตัวอย่างนี้สาธิตวิธีแก้ปัญหา ListView หดตัว (Collapse) เมื่อวางอยู่ใน ScrollView โดยคำนวณความสูงรวมของ ListView และตั้งค่า LayoutParams ให้เต็มความสูง
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
เปิด Android Studio เลือก File → New Project
ขั้นตอนที่ 2: 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="16dp"
android:fillViewport="true"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Content above ListView"
android:textSize="18sp"
android:textStyle="bold"
android:padding="16dp" />
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Content below ListView"
android:textSize="18sp"
android:textStyle="bold"
android:padding="16dp" />
</LinearLayout>
</ScrollView>
ขั้นตอนที่ 3: MainActivity.kt
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"
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "KotlinApp"
val listView = findViewById<ListView>(R.id.listView)
listView.adapter = ArrayAdapter(
this,
android.R.layout.simple_list_item_1,
listViewArray
)
// เรียกฟังก์ชันคำนวณความสูงหลังจาก setAdapter
ListHelper.setListViewHeightBasedOnItems(listView)
}
}
ขั้นตอนที่ 4: Helper Class (ListHelper.kt)
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.ListAdapter
import android.widget.ListView
object ListHelper {
fun setListViewHeightBasedOnItems(listView: ListView) {
val listAdapter = listView.adapter ?: return
var totalHeight = 0
val desiredWidth = View.MeasureSpec.makeMeasureSpec(
listView.width,
View.MeasureSpec.AT_MOST
)
for (i in 0 until listAdapter.count) {
val listItem = listAdapter.getView(i, null, listView)
listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED)
totalHeight += listItem.measuredHeight
}
// เพิ่มความสูงของ Divider
val params = listView.layoutParams
params.height = totalHeight + (listView.dividerHeight * (listAdapter.count - 1))
listView.layoutParams = params
listView.requestLayout()
Log.d("ListHelper", "Total ListView height: $totalHeight px")
}
}
วิธีแก้ปัญหาที่ดีกว่า (Best Practice)
ไม่ควรวาง ListView/RecyclerView ใน ScrollView เพราะ:
- Scrolling behavior จะขัดแย้งกัน (Nested Scrolling)
- Performance แย่ (View recycling ไม่ทำงาน)
- Memory usage สูง
แนะนำ: ใช้ RecyclerView แบบ Nested Scrolling
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false" />
หรือใช้ NestedScrollView + RecyclerView (API 21+)
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout ... >
<!-- Header content -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false" />
<!-- Footer content -->
</LinearLayout>
</androidx.core.widget.NestedScrollView>
ขั้นตอนที่ 5: Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.listviewinscrollview">
<application ... >
<activity android:name=".MainActivity"> ... </activity>
</application>
</manifest>
การทดสอบ
รันแอป จะเห็น ListView แสดงเต็มรายการทั้งหมด 16 ไอเท็ม พร้อม Header และ Footer เลื่อนได้ปกติ