Skip to content

[How to use] How to apply snapping? #172

Description

@Madina-S

Platforms

iOS

Description

I have wrapped ExtendedNestedScrollView into ExtendedNestedScrollView, and on ScrollEndNotification wanted to apply snap, but the UI freezes after scrolling.

My code

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:talim_pro/core/base/base_page.dart';
import 'package:talim_pro/core/constants.dart';

import 'dashboard_cubit.dart';
import 'dashboard_state.dart';

class DashboardPage2
    extends BasePage<DashboardCubit, DashboardBuildable, DashboardListenable> {
  DashboardPage2({super.key});

  final _segments = const ['Process', 'Calendar'];
  final ScrollController outerScrollController = ScrollController();

  @override
  void init(BuildContext context) {
    context.read<DashboardCubit>().getProcesses();
  }

  @override
  void dispose() {
    outerScrollController.dispose();
    super.dispose();
  }

  @override
  Widget builder(BuildContext context, DashboardBuildable state) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final cellWidth = MediaQuery.of(context).size.width / 7;
    final dayDesiredHeight = 64.h;
    final statusBarHeight = MediaQuery.of(context).padding.top;

    return DefaultTabController(
      length: _segments.length,
      initialIndex: state.currentIndex,
      child: NotificationListener(
        onNotification: (notification) {
          if (notification is ScrollEndNotification) _snapToNearest();
          return false;
        },
        child: ExtendedNestedScrollView(
          controller: outerScrollController,
          onlyOneScrollInBody: true,
          pinnedHeaderSliverHeightBuilder: () {
            final commonHeight = statusBarHeight + tabBarHeight;
            return state.currentIndex == 0
                ? commonHeight
                : commonHeight + calendarHeaderHeight;
          },
          headerSliverBuilder: (context, innerBoxIsScrolled) {
            return [
              SliverPersistentHeader(
                pinned: true,
                floating: false,
                delegate: _UnifiedHeaderDelegate(),
              ),
            ];
          },
          body: Builder(
            builder: (context) {
              final tabController = DefaultTabController.of(context);

              return TabBarView(
                controller: tabController,
                physics: const NeverScrollableScrollPhysics(),
                children: [
                  _buildProcessList(context, state),
                  _buildCustomPageCalendar(
                    context,
                    isDark,
                    cellWidth / dayDesiredHeight,
                  ),
                ],
              );
            },
          ),
        ),
      ),
    );
  }

  void _snapToNearest() {
    if (!outerScrollController.hasClients) return;

    if (outerScrollController.position.isScrollingNotifier.value) return;

    final scrollDistance = greetingAppBarHeight;

    if (outerScrollController.offset > 0 &&
        outerScrollController.offset < scrollDistance) {
      final double snapOffset =
      outerScrollController.offset / scrollDistance > 0.5
          ? scrollDistance
          : 0;

      Future.microtask(
            () => outerScrollController.animateTo(
          snapOffset,
          duration: Duration(milliseconds: 200),
          curve: Curves.easeIn,
        ),
      );
    }
  }
}

Try do it

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions