Flutter의 사용자 지정 드래그 가능한 바텀 시트

안녕하세요 👋!
Flutter에서 Draggable 바텀 시트를 찾고 계십니까? 그런 다음 올바른 장소에 착륙했습니다.
먼저 Draggable 하단 시트가 어떻게 보이는지 봅시다.


접근 방식을 코딩하고 전체 섹션을 작은 단계로 나누어 보겠습니다.
1단계: 상용구 코드 코딩
isSwipeUp이라는 전역 부울 변수를 선언하고 false로 초기화합니다.


import 'package:flutter/material.dart';
bool isSwipeUp =false;
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Home(),
    );
  }
}



2단계: 홈페이지용 코드 작성
Home()을 StatefulWidget으로 만들기
위젯을 다른 위젯에 배치하므로 사용합니다Stack().

스택 요소는 서로 위에 배치되며 마지막 요소는 맨 위에 있습니다.

Stack()에서 두 가지 위젯을 사용합니다.
  • 메인스크린()
  • CustomBottomSheet()

  • class Home extends StatefulWidget {
      const Home({Key? key}) : super(key: key);
    
      @override
      State<Home> createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      @override
      Widget build(BuildContext context) {
        Size size = MediaQuery.of(context).size;
        return SafeArea(
          child: Scaffold(
            body: Container(
              color: Colors.black26,
              height: size.height,
              width: size.width,
              child: Stack(
                children: [
                  MainPage(), // [Will create in next step]
                  Positioned(
                    top: size.height * 0.8, //position to be changed  
                      child: const CustomBottomSheet() // [Will create in next step]
                   )
                ],
              ),
            ),
          ),
        );
      }
    }
    

    3단계: MainScreen() 만들기
    MainScreen은 Text() => "HomePage"와 일종의 스타일 지정 및 중앙 정렬이 있는 단일 자식이 있는 하나의 Container()만 있기 때문에 매우 간단합니다.

    class MainPage extends StatelessWidget {
      const MainPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.amber,
          child: const Center(child: Text("HomePage",style: TextStyle(color: Colors.white,fontSize: 22),),),
        );
      }
    }
    


    다음 단계로 넘어가자

    4단계: CustomBottomSheet() 만들기
    CustomBottomSheet에는 위쪽 가장자리에 둥근 모서리가 있고 일종의 스타일이 있는 화면의 전체 너비와 절반 높이가 있는 Container()가 있습니다.

    class CustomBottomSheet extends StatefulWidget {
      const CustomBottomSheet({Key? key}) : super(key: key);
    
      @override
      State<CustomBottomSheet> createState() => _CustomBottomSheetState();
    }
    
    class _CustomBottomSheetState extends State<CustomBottomSheet> {
      @override
      Widget build(BuildContext context) {
        Size size = MediaQuery.of(context).size;
        return Container(
          height: size.height * 0.5,
          width: size.width,
          decoration: const BoxDecoration(
              gradient: LinearGradient(colors: [
                Color.fromRGBO(26, 41, 128, 100),
                Color.fromRGBO(42, 178, 252, 100),
              ]),
              borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(50), topRight: Radius.circular(50))),
                  child: Align(alignment: Alignment.topCenter,
                  child: (isSwipeUp)
                        ? Icon(
                            Icons.expand_more_outlined,
                            size: 30,
                            color: Colors.white,
                          )
                        : Icon(
                            Icons.expand_less_outlined,
                            size: 30,
                            color: Colors.white,
                          ),
                  ),
        );
      }
    }
    


    이제 앱의 이 단계에서 다음과 같이 보입니다.



    5단계: 드래그할 수 있도록 CustomBottomSheet()에 GestureDetector를 추가합니다.

    이제 드래그/스와이프 동작을 감지해야 합니다.
    그러나 flutter에는 멋진 위젯이 있으므로 걱정하지 마십시오GestureDetector().
    GestureDetector()는 Widget에서 모든 종류의 제스처를 감지하는 데 도움이 되며 다양한 속성이 있지만 일부만 사용하겠습니다.

    스택의 CustomBottomSheet()에 GestureDetector() 추가

    GestureDetector(
               onPanEnd: (details) {
                      print(details.velocity.pixelsPerSecond.dy.toString());
                      print(details.velocity.pixelsPerSecond.dx.toString());
               if (details.velocity.pixelsPerSecond.dy > -100) {
                        setState(() {
                          isSwipeUp = true;
                        });
                      } 
    
                   else {
                        setState(() {
                          isSwipeUp = false;
                        });
                      }
                 },
                       child: const CustomBottomSheet())
    


    이제 isSwipeUp이 변경됨에 따라 CustomBottomSheet()의 위치가 변경됩니다.
    전환이 부드러워야 하므로 Positioned()를 AnimatedPositioned()로 교체하고 지속 시간은 400밀리초입니다.
    포지셔닝➡➡ 애니메이션포지셔닝

    top: !isSwipeUp? size.height *0.5:size.height * 0.8,
    


    전체 구성 요소는 다음과 같습니다.

    AnimatedPositioned(
           curve: Curves.decelerate,
            duration: const Duration(milliseconds: 400),
                top: !isSwipeUp? size.height *0.5:size.height * 0.8,
                     child: GestureDetector(
                        onPanEnd: (details) {           print(details.velocity.pixelsPerSecond.dy.toString());
               if (details.velocity.pixelsPerSecond.dy > -100) {
                        setState(() {
                          isSwipeUp = true;
                        });
                      } else {
                        setState(() {
                          isSwipeUp = false;
                        });
                      }
                    },
                          child: const CustomBottomSheet())
               )
    


    우리의 작업이 완료되었습니다🙌🙌.

    Full code:-

    날 잡아봐

    좋은 웹페이지 즐겨찾기