Flutter
패키지
Modal Bottom Sheet

Modal Bottom Sheet

Floating Modal Page

pub.dev 페이지 (opens in a new tab)

IconButton( // (1)
  onPressed: () {
  showFloatingModalBottomSheet(
      context: context,
      builder: (context) {
          return ModalFit();
      });
  },
  icon: Icon(Icons.category))

FloatingModal class

class FloatingModal extends StatelessWidget {
  final Widget child;
  final Color? backgroundColor;
 
  const FloatingModal({Key? key, required this.child, this.backgroundColor})
      : super(key: key);
 
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 20),
        child: Material(
          color: backgroundColor,
          clipBehavior: Clip.antiAlias,
          borderRadius: BorderRadius.circular(12),
          child: child,
        ),
      ),
    );
  }
}

showFloatingModalBottomSheet 함수

Future<T> showFloatingModalBottomSheet<T>({
required BuildContext context,
required WidgetBuilder builder,
Color? backgroundColor,
}) async {
final result = await showCustomModalBottomSheet(
    context: context,
    builder: builder,
    containerWidget: (_, animation, child) => FloatingModal(
          child: child,
        ),
    expand: false);
 
return result;
}

CategoryModalFit(리스트)

FloatingModalBottomSheet에 보여지는 List Tile

class ModalFit extends StatelessWidget {
ModalFit({Key? key}) : super(key: key);
List<String> items = ['Item1', 'item2', 'Item3', 'Item4'];
 
@override
Widget build(BuildContext context) {
  return Material(
      child: SafeArea(
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        ...List.generate(items.length, (index) {
          return ListTile(
            title: Text(items[index]),
            leading: Icon(Icons.insert_emoticon),
            onTap: () => Navigator.of(context).pop(),
          );
        }),
      ],
    ),
  ));
}
}

Cupertino modal with stop

modal size 조정이 가능한 modal sheet sheet package (opens in a new tab)를 사용해야지 쓸 수 있다.

Navigator.of(context).push(
  CupertinoSheetRoute<void>(
      initialStop: 0.5,
      stops: <double>[0, 0.5, 1],
      // Screen은 이동할 스크린
      builder: (BuildContext context) => Screen(),
    ),
  )

부모 위젯 작아지는 애니메이션

아래와 같이 route를 onGenerateRoute로 설정해주고 MaterialExtendedPageRoute를 사용하면 부모 위젯이 작아지는 애니메이션을 사용할 수 있다.

@override
Widget build(BuildContext context) {
  return MaterialApp(
    initialRoute: '/',
    onGenerateRoute: _onGenerateRoute,
  );
}
 
MaterialPageRoute? _onGenerateRoute(settings) {
  switch (settings.name) {
    case('/'):
      return MaterialExtendedPageRoute(builder: ((_) => RootTab()));
      ...
  }
}