Overview.
showModalBottomSheet 를 사용해보자 그안에서 FloatingActionButton 과 showMaodalBottomSheet 가 사용될 예정이다.
showModalBottomSheet의 build 에는 BottomSheet 위젯이 사용된다.
- 일단 padding , viewInsets , viewPadding 에 대해 알아보자
- showModalBottomSheet 란?
0. 문서
https://api.flutter.dev/flutter/material/showModalBottomSheet.html
https://api.flutter.dev/flutter/widgets/MediaQueryData-class.html
1. 일단 padding , viewInsets , viewPadding 에 대해 알아보자
1. 용어정리
(1) padding : 여백
(2) viewInsets : 시스템 UI, 일반적으로 장치의 키보드에 의해 완전히 가려지는 디스플레이 부분
(3) padding = viewPadding - viewInsets
2. 중요개념
padding을 50을 준다고 가정하자.
그러면 실제로는 viewPadding = 50 이 들어온다.
그리고 나서 viewPadding - viewInsets을 계산하게 되는데 viewInsets은 보통 0이니까 padding은 50이 된다.
3. viewInsets가 0이 아니라면?
만약에 키보드가 티어나온다면 어떻게 될까? 키보드 높이는 200이다.
padding을 50을 준다고 똑같이 가정했을때
viewPadding = 50
viewInsets = 200
padding = 50 - 200 이 된다. -150이 되게 되는데 이때 padding은 음수가 아니라 0이 된다.
4. 키보드가 호출된 상황에서는 어떻게 하면 될까?
키보드가 올라오게 되어도 위 상황을 잘만 이용하면 키보드가 화면을 가리지 않는다. 왜?
키보드 높이 200인데
padding에 220을 주면
view Padding = 220
viewInsets = 200
padding = 220 - 200 이니까 패딩이 20남게 된다.
그러면 키보드가 앱 UI를 가리지 않게 된다.
이것을 동적으로 줘야 하는데 그 방법은 MediaQuery를 이용하는 것이다.
MediaQuery.of(context).viewInsets.bottom 이 값은 키보드 높이가 될 것이다.
이 키보드 높이만큼 여백을 주면 된다.
2. showModalBottomSheet
모달 머티리얼 디자인 하단 시트를 표시합니다.
모달 하단 시트는 메뉴나 대화 상자의 대안이며 사용자가 앱의 나머지 부분과 상호 작용하는 것을 방지합니다.
밀접하게 관련된 위젯은 사용자가 앱과 상호 작용하는 것을 방해하지 않으면서 앱의 기본 콘텐츠를 보완하는 정보를 표시하는 영구 하단 시트입니다. showBottomSheet 함수 또는 ScaffoldState.showBottomSheet 메서드를 사용하여 영구 하단 시트를 만들고 표시할 수 있습니다 .
매개 변수는 이것이 DraggableScrollableSheet 를 isScrollControlled 활용하는 하단 시트에 대한 경로인지 여부를 지정합니다 . 이 하단 시트에 ListView 또는 GridView 와 같은 스크롤 가능한 하위 항목이 있는 경우 하단 시트를 드래그할 수 있도록 하려면 이 매개변수를 true로 설정하는 것이 좋습니다.
매개 isDismissible변수는 사용자가 스크림을 탭할 때 바텀 시트를 닫을지 여부를 지정합니다.
매개 enableDrag변수는 바텀 시트를 위아래로 드래그하고 아래로 스와이프하여 닫을 수 있는지 여부를 지정합니다.
매개 useSafeArea변수는 시트가 상단, 왼쪽 및 오른쪽에서 시스템 침입을 방지할지 여부를 지정합니다. false인 경우 SafeArea 가 추가되지 않습니다. MediaQuery.removePadding 이 상단에 적용되므로 상단의 시스템 침입 도 하단 시트 내부의 SafeArea 에 의해 방지되지 않습니다. 기본값은 거짓입니다.
선택적 backgroundColor, elevation, shape, clipBehavior및 매개변수 constraints를 전달하여 모달 하단 시트의 모양과 동작을 사용자 정의할 수 있습니다(자세한 내용은 BottomSheettransitionAnimationController 에 대한 설명서 참조 ).
transitionAnimationController하단 시트의 시작 및 종료 애니메이션을 제어합니다 . 컨트롤러가 더 이상 필요하지 않을 때 AnimationController.dispose를 호출하는 것은 컨트롤러 소유자의 몫입니다 .
선택적 매개변수는 모달 하단 시트 시트의 RouteSettings를settings 설정합니다 . 이는 사용자가 NavigatorObserver 내에서 PopupRoute 를 관찰하려는 경우에 특히 유용합니다 .
DisplayFeature 는 화면을 하위 화면으로 분할할 수 있습니다. 가장 가까운 것이 anchorPoint콘텐츠를 렌더링하는 데 사용됩니다.
아니요가 anchorPoint제공되면 방향성이 사용됩니다.
네.. 그냥 한번 보죠
네 보셨다 시피 위와 같이 가능한겁니다!!
코드로 보죠
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: _Home(),
);
}
}
class _Home extends StatelessWidget {
const _Home({super.key});
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Text("안녕"),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
showModalBottomSheet(
isScrollControlled: true, // 스크롤 기능
context: context, // 현재 컨텍스트
builder: (context) => _buildContainer(context),
);
},
),
),
);
}
Widget _buildContainer(BuildContext context) {
// inset : 삽입이란 뜻이다.
// 쉽게 말해 가려진 크기 [현재는 텍스트창] 이다.
print("inset : ${MediaQuery.of(context).viewInsets.bottom}");
print("padding : ${MediaQuery.of(context).viewPadding.bottom}");
var bottom = MediaQuery.of(context).viewInsets.bottom;
return BottomSheet(
onClosing: () => print("닫아짐"),
builder: (context) => Container(
// 키보드 높이에 따라 padding 값을 추가
padding: EdgeInsets.only(bottom: bottom),
color: Colors.yellow,
// 텍스트 창
child: Container(
color: Colors.red,
height: 200, // 전체 크기
child: TextField(),
),
),
);
}
}
조금 훑어 볼까요?
FloatingActionButton 을 클릭시 showModalBottomSheet 를 호출하게 됩니다.
isScrollControlled : true // 스크롤 가능
context : context // 현재 컨텍스트
builder : (context) => ButtonSheet 위젯
순으로 ButtonSheet 위젯을 빌드하게 됩니다.
ButtonSheet 에는 onClosing 과 builder 를 구현해야합니다.
이때 중요한것이 바로 MediaQuery 인데요 MediaQuery 는 현재 컨텍스트의 크기 , 가려진 부분 크기 등등 볼 수 있는 아주 용한 위젯입니다.
따라서
var bottom = MediaQuery.of(context).viewInsets.bottom;
해당 키보드에 가려진 크기를 알아낸 값을 bottom 변수에 값을 넣고 그 값을 padding 에 추가시켜주면 텍스트창이 올라와도 가려지지 뒤의 container 가 가려지지 않게 할 수 있습니다.!!!
BottomSheet(
onClosing: () => print("닫아짐"),
builder: (context) => Container(
// 키보드 높이에 따라 padding 값을 추가
padding: EdgeInsets.only(bottom: bottom),
color: Colors.yellow,
// 텍스트 창
child: Container(
color: Colors.red,
height: 200, // 전체 크기
child: TextField(),
),
),
);
'flutter & dart' 카테고리의 다른 글
flutter & dart - BoxConstraints (0) | 2024.04.01 |
---|---|
flutter & dart - CircularProgressIndicator (0) | 2024.04.01 |
flutter & dart - BottomNavigationBar , IndexedStack 위젯 (0) | 2024.04.01 |
flutter & dart - 블러 처리(모자이크)를 해보자 BackdropFilter (0) | 2024.04.01 |
flutter & dart - Align 위젯 (0) | 2024.04.01 |