1.플러터 레이아웃 속성 정리
1. Flexible
- 레이아웃 비율을 설정하는 위젯
Expanded
와 유사하나, 특정 비율로 공간 분배 가능
- 부모 위젯의 남는 공간을 효율적으로 사용
2. shrinkWrap
- 스크롤 가능한 위젯의 크기를 내용에 맞춤
true
: 자식 위젯의 크기에 따라 축소
false
: 부모 위젯의 전체 공간 차지
3. resizeToAvoidBottomInset
- 키보드가 화면을 가리지 않도록 조정
true
: 키보드 표시 시 화면 자동 조정
false
: 화면 레이아웃 고정, 키보드가 일부 가릴 수 있음
2. 예시코드와 출력
1. 간단한 텍스트 필드와 키보드인셋
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
// MaterialApp 위젯으로 애플리케이션 전체 설정
return const MaterialApp(
home: LoginPage(), // 홈 화면으로 LoginPage 설정
);
}
}
class LoginPage extends StatelessWidget {
const LoginPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
// 키보드가 올라올 때 화면이 자동 조정되도록 설정
resizeToAvoidBottomInset: true,
body: Column(
children: [
Flexible(
// Flexible로 위젯을 남는 공간에 맞게 확장
child: ListView(
// ListView의 크기를 내용에 맞추기 위해 shrinkWrap 설정
shrinkWrap: true,
children: [
// 높이 400의 빨간색 컨테이너
Container(
height: 400,
color: Colors.redAccent,
),
// 세 개의 입력 필드
TextFormField(),
TextFormField(),
TextFormField(),
],
),
),
// 로그인 버튼
ElevatedButton(
onPressed: () {}, // 버튼 클릭 시 동작 정의
child: Text("로그인"), // 버튼 텍스트
)
],
),
);
}
}

2. 스크롤 심화
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
// 애플리케이션의 루트 위젯 설정
return MaterialApp(
home: HomePage(), // 초기 화면으로 HomePage 설정
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final ScrollController _controller = ScrollController(); // 스크롤 컨트롤러 생성
double prev = 0; // 이전 스크롤 위치 저장 변수
double height = 300; // 상단 컨테이너의 초기 높이
@override
void initState() {
super.initState();
// 스크롤 이벤트 리스너 추가
_controller.addListener(() {
scrollListener();
});
}
// 스크롤 동작 처리 함수
void scrollListener() {
print("스크롤 동작중");
double currentOffset = _controller.offset; // 현재 스크롤 위치
print("currentOffset : $currentOffset");
// 상단 컨테이너의 높이를 스크롤에 따라 변경
if (currentOffset < 300) {
setState(() {
height = 300 - currentOffset; // 스크롤 위치에 따라 높이 감소
if (height < 56) {
height = 56; // 최소 높이 제한
}
});
}
// 스크롤 방향 확인
if (currentOffset > prev) {
print("아래로 내려가요"); // 아래 방향 스크롤
}
if (currentOffset < prev) {
print("위로 올라가요"); // 위 방향 스크롤
}
// 스크롤 위치가 최하단일 경우
if (currentOffset == _controller.position.maxScrollExtent) {
print("가장 하단");
}
// 스크롤 위치가 최상단일 경우
if (currentOffset == _controller.position.minScrollExtent) {
print("가장 위");
}
prev = currentOffset; // 이전 스크롤 위치 업데이트
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
// 상단 컨테이너 (높이 변화)
Container(
color: Colors.red, // 배경색 빨강
height: height, // 동적으로 변화하는 높이
width: double.infinity, // 가로로 화면 전체
child: Center(
child: Text(
"Good", // 텍스트
style: TextStyle(
color: Colors.white, // 글자색 흰색
fontSize: height / 3, // 높이에 따라 동적으로 글자 크기 변경
),
),
),
),
// 리스트뷰
Expanded(
child: ListView.builder(
controller: _controller, // 스크롤 컨트롤러 연결
itemCount: 50, // 항목 50개 생성
itemBuilder: (context, index) => Text("제목 $index"), // 리스트 아이템 텍스트
),
),
],
),
),
);
}
}

Share article