ListView안에 ListView는 크기가 정해져야 한다

송민경's avatar
Apr 11, 2024
ListView안에 ListView는 크기가 정해져야 한다

  • Expanded Column
  • 객체를 3~4개 정도 만들어서 1~2개씩 빌드해서 사용
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Container( height: 500, color: Colors.red, ), Expanded( child: ListView.builder( itemCount: 10, // 데이터로 받은 데이터의 길이 넣기 itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.only(top: 5), child: Container( height: 100, color: Colors.blue, ), ); }, ), ), ], ), ); } }
  • 스크롤 하면 내용이 위로 올라와서 많이 보이길 바람
notion image
  • ListView + SizedBox
  • 스크롤 안에 스크롤이 있으니 부모의 스크롤만 인식되서 빨간색만 스크롤이 됨
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: ListView( children: [ Container( height: 500, // 이 높이만큼 화면에 보임 color: Colors.red, ), SizedBox( height: 500, child: ListView.builder( itemCount: 10, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.only(top: 5), child: Container( height: 100, color: Colors.blue, ), ); }, ), ), ], ), ); } }
  • 스크롤을 공유하지 않음
  • 높이를 정확히 계산해서 보여야함
꽉 채운 화면으로 보면 (빨간색이 없으면) 복구가 안됨
1050이라고 세로를 픽스해놓을 수 없음 → 변수화 시켜야 함
notion image
notion image
notion image
  • NestedScrollView
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: const HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: NestedScrollView( headerSliverBuilder: (context, _) { return [ SliverAppBar( title: const Text('Scroll Sharing'), floating: true, snap: true, ), ]; }, body: ListView( children: [ Container( height: 500, color: Colors.red, ), SizedBox( height: 1050, child: ListView.builder( physics: const NeverScrollableScrollPhysics(), itemCount: 10, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.only(top: 5), child: Container( height: 100, color: Colors.blue, ), ); }, ), ), ], ), ), ); } }
notion image
notion image
notion image
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: const HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: NestedScrollView( // 헤더와 바디의 위젯이 스크롤을 공유하는 list headerSliverBuilder: (context, _) { // 헤더부분 return [ SliverList( delegate: SliverChildListDelegate([ Container( // 6장에 이미지들을 여기다 넣으면 됨 height: 500, color: Colors.red, ), ]), ), ]; }, body: ListView.builder( // 바디부분 physics: const NeverScrollableScrollPhysics(), itemCount: 10, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.only(top: 5), child: Container( height: 100, color: Colors.blue, ), ); }, ), ), ); } }
notion image
class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: NestedScrollView( // 헤더와 바디의 위젯이 스크롤을 공유하는 list headerSliverBuilder: (context, _) { // 헤더부분 return [ SliverList( delegate: SliverChildListDelegate([ Container( // 6장에 이미지들을 여기다 넣으면 됨 height: 500, color: Colors.red, ), Container( // 6장에 이미지들을 여기다 넣으면 됨 height: 500, color: Colors.yellow, ), pinned: false, floating: true, snap: true, ]), ), ]; },
 
→ 응용하기
  • 높이 계산이 필요 없음
import 'package:flutter/material.dart'; import 'package:profile_app/theme.dart'; import 'components/profile_buttons.dart'; import 'components/profile_count_info.dart'; import 'components/profile_drawer.dart'; import 'components/profile_header.dart'; import 'components/profile_tab.dart'; import 'components/profile_tap2.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: theme(), home: ProfilePage(), ); } } class ProfilePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( endDrawer: ProfileDrawer(), appBar: _buildProfileAppBar(), body: NestedScrollView( headerSliverBuilder: (context, _) { return [ SliverList( delegate: SliverChildListDelegate([ ProfileHeader(), SizedBox(height: 20), ProfileCountInfo(), SizedBox(height: 20), ProfileButtons(), ]), ), ]; }, body: ProfileTab(), )); } AppBar _buildProfileAppBar() { return AppBar( leading: Icon(Icons.arrow_back_ios), title: Text("Profile"), centerTitle: true, ); } }
notion image
 
Share article

vosw1