7. 키보드문제 스크롤(scroll) 처리방법

강재영's avatar
Oct 02, 2024
7. 키보드문제 스크롤(scroll) 처리방법
 
 
💡
키보드가 올라올 때 입력 필드가 제대로 스크롤되지 않거나, 입력 필드가 가려지면서 UI가 깨지는 상황
 

1. 키보드가 올라 올때 높이를 가지는데 이때 처리를 안하면 에러

notion image
 
 

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

notion image
 
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로 감싸서 키보드가 위로 올라오면 그만큼 높이가 작아지기만해서 따로 처리를 안해도 됨 이 방법이 좋아보임
 

이 방법의 장점

  1. 효율적인 레이아웃 관리: ListView 전체를 Scaffold 안에 배치하는 대신, Column으로 레이아웃을 나누고 ListView는 필요한 부분만을 스크롤 가능하게 만들 수 있습니다.
  1. Expanded의 활용: Expanded 위젯은 남은 공간을 채우며, ListViewExpanded로 감싸면 다른 위젯들과 공간을 효율적으로 나눌 수 있습니다. 키보드가 올라올 때 ListView의 높이도 자동으로 줄어들기 때문에 따로 스크롤 처리를 하지 않아도 됩니다.
  1. 키보드 처리 간소화: 키보드가 올라올 때 전체 화면의 높이가 줄어들면서 ListView의 크기도 자동으로 조정되기 때문에, 추가적으로 키보드 높이에 맞춰 스크롤을 조정하는 코드를 작성할 필요가 없습니다.
 
Share article

강재영 블로그