키보드가 올라올 때 입력 필드가 제대로 스크롤되지 않거나, 입력 필드가 가려지면서 UI가 깨지는 상황
1. 키보드가 올라 올때 높이를 가지는데 이때 처리를 안하면 에러

2.해결책 1.키보드가 올라 올떄 그 높이값을 구해서 그만 큼 스크롤하는 방법

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(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
ScrollController? con;
@override
void initState() {
super.initState();
con = new ScrollController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: ListView(
controller: con, // ScrollController 바인딩
children: [
buildChat("허위"),
buildChat("13123232"),
buildChat("반가워요1"),
buildChat("반가워요2"),
buildChat("반가워요3"),
buildChat("반가워요4"),
buildChat("반가워요5"),
TextFormField(
onTap: () {
// 0.5초 딜레이를 줘(왜냐면 스크롤이 0.5초 뒤는 생기니까)
// MediaQuery로 keyboard 높이를 알수 있어
Future.delayed(Duration(milliseconds: 500), () {
con!.animateTo(
con!.offset + MediaQuery.of(context).viewInsets.bottom,
curve: Curves.linear,
duration: Duration(milliseconds: 500));
});
},
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
hintText: "Chat anything...",
),
),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {},
child: Text("전송",
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.white)),
style: ElevatedButton.styleFrom(backgroundColor: Colors.green),
),
)
],
),
),
);
}
Widget buildChat(String title) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
backgroundImage: NetworkImage(
"https://cdn.imweb.me/thumbnail/20240220/105cc1508cf03.png",
),
),
SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"홍길동 선생님",
style: TextStyle(fontWeight: FontWeight.bold),
),
Container(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Text(title),
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
),
],
),
),
],
),
);
}
}
3. 두번째 방법
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
// ScrollController 바인딩
children: [
Expanded(
child: ListView(
controller: con,
children: [
buildChat("허위"),
buildChat("2323"),
buildChat("반가워요3"),
buildChat("반가워요4"),
buildChat("반가워요5"),
buildChat("반가워요5"),
buildChat("반가워요5"),
],
),
),
원래는 전체를 ListView를 잡고 진행 했다면 이번에는 특정 부분을 ListView로 잡고 그부분을 Expanded로 감싸서 키보드가 위로 올라오면 그만큼 높이가 작아지기만해서 따로 처리를 안해도 됨 이 방법이 좋아보임
이 방법의 장점
- 효율적인 레이아웃 관리:
ListView
전체를Scaffold
안에 배치하는 대신,Column
으로 레이아웃을 나누고ListView
는 필요한 부분만을 스크롤 가능하게 만들 수 있습니다.
Expanded
의 활용:Expanded
위젯은 남은 공간을 채우며,ListView
를Expanded
로 감싸면 다른 위젯들과 공간을 효율적으로 나눌 수 있습니다. 키보드가 올라올 때ListView
의 높이도 자동으로 줄어들기 때문에 따로 스크롤 처리를 하지 않아도 됩니다.
- 키보드 처리 간소화: 키보드가 올라올 때 전체 화면의 높이가 줄어들면서
ListView
의 크기도 자동으로 조정되기 때문에, 추가적으로 키보드 높이에 맞춰 스크롤을 조정하는 코드를 작성할 필요가 없습니다.
Share article