오늘은 네이버 바텀 시트를 끝내보려 한다

지금 까지 내가한건 네이버 시트에 상태를 알 수 있게 state에서 관리해 view로 넘겨주는 작업을 완료하였다.

이게 정말 좋은 상태관리와 책임 분리인지는 고민이지만 조금 더 내목표를 위해 노력해보고자 화이팅

먼저 내 패널은

 ShortPanel(
          onPressed: () {
            context
                .read<NaverMapCubit>()
                .updatePanelState(BottomSheetState.expanded);
          },
        ),

아렇게 숏 판넬 위젯이 연결이 되어있다.

맞다 나는 사용자가 드레그하거나 선택을 클릭하면

숏판넬이 아닌 롱 판넬을 보여주기 위해 기획하고 있다

그럼 먼저 간단하게 롱 판넬을 만들어볼까?

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:my_dream/Page/12_naver_map/page/NaverMapApp_cubit.dart';
import 'package:my_dream/Page/12_naver_map/page/NaverMapApp_state.dart';
import 'package:my_dream/Page/12_naver_map/page/bottom_sheet/widget/short_panel.dart';
import 'package:sliding_up_panel/sliding_up_panel.dart';

class SlidingPanel extends StatelessWidget {
  const SlidingPanel({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<NaverMapCubit, NaverMapState>(builder: (context, state) {
      return SlidingUpPanel(
        controller: state.panelController,
        minHeight: 0,
        maxHeight: MediaQuery.of(context).size.height -
            MediaQuery.of(context).padding.top,
        borderRadius: const BorderRadius.vertical(top: Radius.circular(8)),
        snapPoint: 0.223,
        onPanelClosed: () {
          if (state.panelState != BottomSheetState.closed) {
            context
                .read<NaverMapCubit>()
                .updatePanelState(BottomSheetState.closed);
          }
        },
        onPanelSlide: (double position) {
          if (position > 0.22 &&
              position < 0.23 &&
              state.panelState != BottomSheetState.half) {
            context
                .read<NaverMapCubit>()
                .updatePanelState(BottomSheetState.half);
          } else if (position > 0.3 &&
              state.panelState != BottomSheetState.expanded) {
            context
                .read<NaverMapCubit>()
                .updatePanelState(BottomSheetState.expanded);
          }
        },
        panel: ShortPanel(
          onPressed: () {
            context
                .read<NaverMapCubit>()
                .updatePanelState(BottomSheetState.expanded);
          },
        ),
      );
    });
  }
}

아래와 같이 애니메이션 스위치로 변경

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:my_dream/Page/12_naver_map/page/NaverMapApp_cubit.dart';
import 'package:my_dream/Page/12_naver_map/page/NaverMapApp_state.dart';
import 'package:my_dream/Page/12_naver_map/page/bottom_sheet/widget/long_panel.dart';
import 'package:my_dream/Page/12_naver_map/page/bottom_sheet/widget/short_panel.dart';
import 'package:sliding_up_panel/sliding_up_panel.dart';

class SlidingPanel extends StatelessWidget {
  const SlidingPanel({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<NaverMapCubit, NaverMapState>(
      builder: (context, state) {
        print('패널 상태: ${state.panelState}');
        return SlidingUpPanel(
          controller: state.panelController,
          minHeight: 0,
          maxHeight: MediaQuery.of(context).size.height -
              MediaQuery.of(context).padding.top,
          borderRadius: const BorderRadius.vertical(top: Radius.circular(8)),
          snapPoint: 0.223,
          onPanelClosed: () {
            if (state.panelState != BottomSheetState.closed) {
              context
                  .read<NaverMapCubit>()
                  .updatePanelState(BottomSheetState.closed);
            }
          },
          onPanelSlide: (double position) {
            if (position > 0.22 &&
                position < 0.23 &&
                state.panelState != BottomSheetState.half) {
              context
                  .read<NaverMapCubit>()
                  .updatePanelState(BottomSheetState.half);
            } else if (position > 0.3 &&
                state.panelState != BottomSheetState.expanded) {
              context
                  .read<NaverMapCubit>()
                  .updatePanelState(BottomSheetState.expanded);
            }
          },
          panel: AnimatedSwitcher(
            duration: const Duration(milliseconds: 300),
            transitionBuilder: (Widget child, Animation<double> animation) {
              return FadeTransition(
                opacity: animation,
                child: child,
              );
            },
            child: state.panelState == BottomSheetState.expanded
                ? const LongPanel() // 확장된 상태의 패널
                : ShortPanel(
                    // 기본 상태의 패널
                    key: const ValueKey('short_panel'),
                    onPressed: () {
                      context
                          .read<NaverMapCubit>()
                          .updatePanelState(BottomSheetState.expanded);
                    },
                  ),
          ),
        );
      },
    );
  }
}

문제가 발생했다……

image.png