패키지, 저장소 및 앱 카테고리 검색

onboarding_overlay 표지
패키지 상세v3.2.3

onboarding_overlay

대상 요소와 함께 또는 없이 온보딩 오버레이를 제어할 수 있도록 유연하게 구성됨 (onboard_overlay에서 파생됨)

AndroidiOSWebmacOSWindowsLinux
30일 다운로드
1만
좋아요
375
Pub 점수
150

패키지 설치

flutter pub add onboarding_overlay

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

특정 UI 요소를 대상으로 하거나 타겟 없이 자유롭게 표시할 수 있는 앱 기능을 사용자에게 안내하는 온보딩 오버레이를 생성하기 위한 유연한 Flutter 패키지입니다. onboard_overlay의 포크로 만들어졌으며, 오버레이의 외관과 동작에 대한 커스터마이징 및 제어가 향상되었습니다. 다양한 플랫폼에서 부드럽고 인터랙티브한 튜토리얼을 통해 신규 사용자에게 핵심 기능을 소개하는 데 이상적입니다.

사용 사례

  • 앱 기능을 통해 새 사용자 안내하기
  • 온보딩 중 특정 UI 요소 강조하기
  • 사용자 정의 가능한 튜토리얼 흐름 만들기
  • 다중 플랫폼 온보딩 경험 지원
  • 단계별 안내 통합

주요 기능

  • 대상 또는 자유 부유 오버레이 위치 지정
  • 사용자 정의 가능한 오버레이 외관 및 애니메이션
  • 다중 플랫폼 배포 지원
  • 단계를 위한 유연한 콜백 처리
  • 기존 Flutter 위젯과의 간편한 통합

적합한 대상

  • 앱 온보딩 화면
  • 사용자 교육 흐름
  • 다중 플랫폼 애플리케이션
  • 경량 온보딩 솔루션을 찾는 개발자
  • 비타겟 오버레이 안내가 필요한 프로젝트

고려 사항

  • 중첩된 콘텐츠를 위한 신중한 레이아웃 관리가 필요합니다
  • 일관된 크로스플랫폼 뷰를 위해 추가 스타일링이 필요할 수 있습니다
  • 제한된 내장 테마; 사용자 정의 필요
  • 복잡한 탐색 워크플로에 적합하지 않습니다
  • 명확한 사용자 상호작용 트리거와 함께 사용할 때 가장 효과적입니다

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

Pub

onboarding_overlay

A flexible onboarding widget that can start and stop with an arbitrary number of steps and arbitrary starting point

Demo

Usage

  1. Create your List<FocusNodes> somewhere accessible
final List<FocusNode> overlayKeys = <FocusNode>[
    FocusNode(),
    FocusNode(),
    FocusNode(),
  ];
  1. Create your List<OnboardingSteps> somewhere accessible
final List<OnboardingSteps> steps = [OnboardingStep(
    focusNode: _focusNodes != null ? _focusNodes[0] : null,
    title: "Hi",
    titleTextStyle: Theme.of(context).textTheme.headline5.copyWith(
        color: Theme.of(context).canvasColor,
        ),
    bodyText:
        '''Check this out''',
    bodyTextStyle: Theme.of(context).textTheme.subtitle1.copyWith(
        color: Theme.of(context).canvasColor,
        ),
    hasLabelBox: false,
    fullscreen: true,
    overlayColor: Theme.of(context).primaryColorDark.withOpacity(0.8),
    hasArrow: false,
    ),]
  1. Provide the FocusNodes to the widgets.
Focus(
    focusNode: focusNode[0]
    Text(
        'You have pushed the button this many times:',
    ),
)
  1. Add Onboarding widget to your widget tree below MaterialWidget and above of everything else
void main() {
  runApp(App());
}

class App extends StatefulWidget {
  final GlobalKey<OnboardingState> onboardingKey = GlobalKey<OnboardingState>();

  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  List<FocusNode> focusNodes = <FocusNode>[];

  @override
  void initState() {
    super.initState();

    focusNodes = List<FocusNode>.generate(
      7,
      (int i) => FocusNode(debugLabel: i.toString()),
      growable: false,
    );
  }

  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Onboarding(
          key: widget.onboardingKey,
          steps: steps,
          onChanged: (int index) {
            debugPrint('----index $index');
            if (index == 5) {
              /// interrupt onboarding on specific step
              /// widget.onboardingKey.currentState.hide();
              /// or do something else
            }
          },
          child: Home(
            focusNodes: focusNodes,
          ),
        ),
      );
}
  1. Showing the onboarding
  • On some activity somewhere down the widget tree in another widget with a new BuildContext
final OnboardingState? onboarding = Onboarding.of(context);

if (onboarding != null) {
  onboarding.show();
}
  • Or immediately in initState somewhere down the widget tree in another widget with a new BuildContext
@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) {
    final OnboardingState? onboarding = Onboarding.of(context);
    if (onboarding != null) {
      onboarding.show();
    }
  });
}
  1. The text can be wrapped in a box, than support all kind of decorations and only shape: BoxShape.rectangle For this to happen, you have to set hasLabelBox equal to true, labelBoxDecoration, which supports only BoxDecoration

  2. The Label box also supports having an arrow. This is controlled by hasArrow. The position is not calculated automatically. The default position is top. You will have to specify the position via arrowPosition by using the enum ArrowPosition. The ArrowPosition.top and ArrowPosition.bottom calculates the horizontal position automatically according to the widget of interest (the focused one which is visible through the overlay), the other arrow positions are centered in the label box e.g. ArrowPosition.topCenter, ArrowPosition.bottomCenter. In addition there are 2 new settings from v3.0.0 - ArrowPosition.autoVertical and ArrowPosition.autoVerticalCenter, which will take care of positioning the arrow automatically relative to the label box and widget position.

  3. The onboarding also supports forwarding the onTap event to the widget of interest. You can control the behavior for each step using the overlayBehavior. It accepts the Flutter enum HitTestBehavior. By default, the value used is HitTestBehavior.opaque.

  • HitTestBehavior.opaque ignores the clicks on the focused widget and always will navigate to next step
  • HitTestBehavior.translucent forwards clicks on the focused widget and on the overlay in the same time
  • HitTestBehavior.deferToChild the clicks on the hole are forwarded to the focused widget, clicks on the overlay navigates to next step.
  1. Sometimes the titleText and the bodyText might not fit well in the constrained label box, because of the long texts, longer translations or smaller screens. There are 2 behaviors for this scenario. The default one will limit the title to 2 lines and the bodyText to 5 lines and will overflow both with ellipsis, the second one is to automatically resize the texts. This is controlled by the Onboarding property autoSizeTexts, which default value is false.

  2. The onboarding can show only a portion of the defined steps with a specific start index. Use showWithSteps method. Remember that the steps indexes are 0-based (starting from zero)

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) {
    final OnboardingState? onboarding = Onboarding.of(context);
    if (onboarding != null) {
      onboarding.showWithSteps(3, <int>[3,4,5,6]);
    }
  });
  }
  1. The onboarding can start from a specific index and play until the end step is reached. Use showFromIndex method. Remember that the steps indexes are 0-based (starting from zero)
@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((Duration timeStamp) {
    final OnboardingState? onboarding = Onboarding.of(context);
    if (onboarding != null) {
      onboarding.showFromIndex(3);
    }
  });
}
  1. From v.3.0.0 if you want to show something else, different from just title and explanation text, then stepBuilder is for you. With stepBuilder, you can change the layout, add images or something else.

Important: If you want to inherit your App Theme from your app instead of using the style properties. You need to wrap your stepBuilder code with a Scaffold or Material widgets.

Important: Clicks on the overlay are ignored if stepBuilder is set. Clicks on the hole or on the widget depend on the HitTestBehavior.

  • using HitTestBehavior.translucent and HitTestBehavior.deferToChild will forward clicks on the hole to the focused widget
  • using HitTestBehavior.opaque ignores clicks on the hole and on the overlay are ignored. Call callbacks provided by the stepBuilder
OnboardingStep(
  focusNode: focusNodes[0],
  titleText: 'Tap anywhere to continue ',
  titleTextColor: Colors.black,
  bodyText: 'Tap anywhere to continue Tap anywhere to continue',
  labelBoxPadding: const EdgeInsets.all(16.0),
  labelBoxDecoration: BoxDecoration(
    shape: BoxShape.rectangle,
    borderRadius: const BorderRadius.all(Radius.circular(8.0)),
    color: const Color(0xFF00E1FF),
    border: Border.all(
      color: const Color(0xFF1E05FB),
      width: 1.0,
      style: BorderStyle.solid,
    ),
  ),
  arrowPosition: ArrowPosition.autoVertical,
  hasArrow: true,
  hasLabelBox: true,
  fullscreen: true,
  stepBuilder: (
    BuildContext context,
    OnboardingStepRenderInfo renderInfo,
  ) {
    return SingleChildScrollView(
      child: Column(
        children: [
          Text(
            renderInfo.titleText,
            style: renderInfo.titleStyle,
          ),
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Image.asset(
                'assets/demo.gif',
                width: 50,
              ),
              const SizedBox(
                width: 10,
              ),
              Flexible(
                child: AutoSizeText(
                  renderInfo.bodyText,
                  style: renderInfo.bodyStyle,
                ),
              ),
            ],
          ),
          Row(
            children: [
              TextButton(
                onPressed: renderInfo.nextStep,
                child: Text('Next'),
              ),
              const SizedBox(
                width: 10,
              ),
              TextButton(
                onPressed: renderInfo.close,
                child: Text('close'),
              ),
            ],
          ),
        ],
      ),
    );
  },
),
  1. From v.3.0.0 Combining onTapCallback with the overlayBehavior gives more control.
  • If you want to capture any clicks and decide what to do depending on the area that was clicked - use HitTestBehavior.opaque
  • if you want to be able to click on the focused widget and control when to go to next step or close - use HitTestBehavior.translucent
  • If you want to capture clicks only on the overlay, the clicks on the hole will not be controlled by the callback - use HitTestBehavior.deferToChild

Using the TapArea you can specify what happens when the user clicked on certain area. The possible options are hole, label and overlay

OnboardingStep(
  focusNode: focusNodes[4],
  titleText: 'Menu',
  bodyText: 'You can open menu from here',
  overlayColor: Colors.green.withOpacity(0.9),
  shape: const CircleBorder(),
  overlayBehavior: HitTestBehavior.translucent,
  onTapCallback:
      (TapArea area, VoidCallback next, VoidCallback close) {
    if (area == TapArea.hole) {
      next();
    }
  },
),
  1. From v.3.0.0 It is possible to combine onTapCallback and stepBuilder. No navigation will be executed except if you call next() method from onTapCallback or the stepBuilder. You can customize the behavior using the TapArea enum to get the area where the user clicked. By using the HitTestBehavior you can again customize if the clicks on the hole are ignored or forwarded to the focused widget. Again if you define the overlayBehavior with HitTestBehavior.deferToChild the click on the hole or the widget in focus will not be controlled by the onTapCallback

  2. From v3.0.0 there is an additional OverlayController (ChangeNotifier) attached to the OverlayState that provides the currentIndex, currentStep and isVisible.

final OnboardingState? onboarding = Onboarding.of(context);
if( onboarding?.controller.isVisible ?? false) {
  // do some logic here
}
  1. From v.3.0.0 you can also add a pulsing animation around the focused widget. Pulse animation will be displayed showPulseAnimation on an OnboardingStep is set to true. In addition you can change the inner and outer colors of the pulse animation. Thanks to the author Gautier of the pal package for the inspiration.
  1. From v.3.0.0 you can show a red border around the label box for debugging purposes by using an Onboarding parameter debugBoundaries which is false by default.
  1. From v.3.1.0 The package can be used with ResponsiveFramework. For this to work as expected you need to perform these changes to your code:

    • move Onboarding widget under the ResponsiveWrapper.builder
    • wrap with a Builder to be able to access the inherited widget for ResponsiveWrapperData
    • manually calculate scale for width and height
    • pass the calculated values to the Onboarding widget.
    • by default these scale values will be 1.0

Example:

return MaterialApp(
      home: ResponsiveWrapper.builder(
        Builder(builder: (context) {
          final ResponsiveWrapperData data = ResponsiveWrapper.of(context);
          final scaleWidth = data.screenWidth / data.scaledWidth;
          final scaleHeight = data.screenHeight / data.scaledHeight;

          return Onboarding(
            key: widget.onboardingKey,
            steps: steps,
            globalOnboarding: true,
            debugBoundaries: true,
            child: const Home(),
            scaleWidth: scaleWidth,
            scaleHeight: scaleHeight,
          );
        }),
        maxWidth: 1200,
        minWidth: 480,
        defaultScale: true,
        breakpoints: [
          const ResponsiveBreakpoint.autoScale(800, name: TABLET),
        ],
      ),
      initialRoute: "/",
    );
  1. From 3.2.1 [stepPainterBuilder] is a callback function that passes the context, the title String, the hole Rect nd if the arrow position isTop bool. By default it is null and it will use the LabelPainter. You can use this to draw custom shapes around the hole. You can use the LabelPainter as a reference

  2. From 3.2.3

  • [animateOverlayHole] is a property that can be set to false to disable the animation of the overlay hole.
  • [labelBoxMargin] property to the OnboardingStep so that the user can control the space around the label box. Especially useful for limiting maximum width of the label box.

Example:

OnboardingStep(
  focusNode: focusNodes[0],
  titleText: 'Tap anywhere to continue ',
  labelBoxMargin: const EdgeInsets.symmetric(horizontal: 16.0), // <--This ensures that there will be always padding around the label box on the left and right sides
  labelBoxDecoration: BoxDecoration(
    shape: BoxShape.rectangle,
    borderRadius: const BorderRadius.all(Radius.circular(8.0)),
    color: const Color(0xFF00E1FF),
  ),
),
  1. From 3.2.4
  • [labelBoxVerticalDistance] property to the OnboardingStep so that the user can customize the space between the label box and the overlay hole.

Example:

OnboardingStep(
  focusNode: focusNodes[0],
  titleText: 'Tap anywhere to continue',
  labelBoxVerticalDistance: 16.0, // default is kSpace = 4.0
),

카테고리

의존성

의존성 목록 2 개

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.