Flutter: 키보드에 가려지는 입력창 문제, Scrollable.ensureVisible로 해결
화면 하단 입력창이 키보드에 가려짐 → 사용자 경험 저해
Scrollable.ensureVisible 적용 → 사용자 경험 향상
기존 방식의 한계
- ScrollController.animateTo 사용
- 문제점
• 부정확한 위치 선정: 실제 포커스된 입력창 보장 불가
• 타이밍 불일치: 키보드 애니메이션과 스크롤 애니메이션 불일치
Scrollable.ensureVisible 소개
- 특정 위젯의 BuildContext 기반 자동 스크롤 위치 조정 기능
- 입력창이 화면 내 완전 표시 보장
구현 방법
- FocusNode 할당 → 입력창 포커스 감지
- initState에서 FocusNode 리스너 추가
- 리스너 콜백 내 Scrollable.ensureVisible 호출
final _idFocusNode = FocusNode();
final _passwordFocusNode = FocusNode();
final _passwordConfirmFocusNode = FocusNode();
final _emailFocusNode = FocusNode();
final _verificationCodeFocusNode = FocusNode();
final _scrollController = ScrollController();
@override
void initState() {
super.initState();
// 포커스 시 스크롤하여 해당 필드를 보이도록 하는 리스너 추가 함수
void addEnsureVisibleListener(FocusNode node) {
node.addListener(() {
if (node.hasFocus) {
// 키보드가 올라오고 레이아웃이 안정화될 시간을 주기 위해 짧은 지연 후 실행
// 이 지연 시간(milliseconds)은 앱의 반응성 및 테스트를 통해 조절할 수 있습니다.
Future.delayed(const Duration(milliseconds: 300), () {
// 위젯이 여전히 마운트 상태이고, FocusNode의 context가 유효한지 확인
if (mounted && node.context != null) {
Scrollable.ensureVisible(
node.context!, // 필수: 포커스된 위젯의 BuildContext
duration: const Duration(milliseconds: 250), // 스크롤 애니메이션 지속 시간
curve: Curves.easeInOut, // 스크롤 애니메이션 커브
alignment: 0.1, // 정렬 옵션: 0.0은 위젯 상단, 0.5는 중앙, 1.0은 하단
// 0.1은 위젯이 뷰포트 상단에서 10% 위치에 오도록 (약간의 여백)
);
}
});
}
});
}
// 각 포커스 노드에 리스너 할당
addEnsureVisibleListener(_idFocusNode);
// ... (다른 FocusNode들에도 동일하게 리스너 할당) ...
// addEnsureVisibleListener(_passwordFocusNode);
// addEnsureVisibleListener(_emailFocusNode);
// addEnsureVisibleListener(_verificationCodeFocusNode);
}
@override
void dispose() {
// ... 컨트롤러 및 FocusNode들 해제 ...
_idFocusNode.dispose();
_scrollController.dispose();
super.dispose();
}
주요 포인트
- Future.delayed: 키보드 애니메이션 완료 대기, 지연 시간은 테스트 후 조정 필요
- mounted && node.context != null: 위젯 제거, FocusNode 무효 상황 대비 안전장치
- alignment: Scrollable.ensureVisible의 alignment 매개변수 활용, 입력창 표시 위치 조정
• 0.0 → 뷰포트 상단
• 0.5 → 중앙
• 0.1 → 상단 여유 공간 확보
Scrollable.ensureVisible 장점
- 정확성: 특정 위젯의 가시성 보장
- 부드러운 경험: duration, curve 지정 통한 자연스러운 스크롤
- 자동 복구: 키보드 종료 시 스크롤 위치 복원 (Flutter 기본 동작 기반)
'Flutter' 카테고리의 다른 글
VScode로 플러터를 개발하는데 필요한 익스텐션 (0) | 2025.09.05 |
---|---|
VSCode 멀티루트 워크스페이스 - 백엔드/프론트 한번에 보기 (0) | 2025.09.05 |
로컬 커머스) 준비작업1 (2) | 2025.08.27 |
로컬 커뮤니티 커머스) 피드백 (1) | 2025.08.25 |
플러터) 게시물작성 코드 구조 (4) | 2025.08.22 |