Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date Picker causes visible jank #58

Open
KristijanZic opened this issue Jun 17, 2023 · 0 comments
Open

Date Picker causes visible jank #58

KristijanZic opened this issue Jun 17, 2023 · 0 comments

Comments

@KristijanZic
Copy link

KristijanZic commented Jun 17, 2023

When I put the date picker in the PageView it makes the PageView swipe animation very janky when it is transitioning on or off the page that contains the flutter holo date picker.
I'm not that familiar with this code base. Could you investigate the issue?

Flutter version: Flutter 3.10.5

Tested devices:
Real testing devices: Google Pixel 6, iPhone 7
Emulators: iPhone 14 Pro, iPhone 14 Pro Max...

Result: Issue shows up in all modes, debug mode more, profile and release mode less but it's visibly there.

Here is the source in one file:

import 'package:flutter/material.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:flutter_holo_date_picker/flutter_holo_date_picker.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        // useMaterial3: true,
      ),
      home: const PagesScreen(),
    );
  }
}

class PagesScreen extends StatefulWidget {
  const PagesScreen({super.key});

  @override
  State<StatefulWidget> createState() => _PagesScreenState();
}

class _PagesScreenState extends State<PagesScreen> {
  final controller = PageController(initialPage: 0);

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

  int pageNumber = 0;

  @override
  Widget build(BuildContext context) {
    List<Widget> pages = [
      const SimplePage(
        title: 'Page 1',
        subtitle: 'Subtitle 1',
      ),
      const SimplePage(
        title: 'Page 2',
        subtitle: 'Subtitle 2',
      ),
      const Picker(
        title: 'Page 3',
        subtitle: 'Subtitle 3',
      ),
    ];

    return SafeArea(
      top: false,
      child: Scaffold(
        body: PageView(
          controller: controller,
          onPageChanged: (pageIndex) {
            setState(() {
              pageNumber = pageIndex;
            });
          },
          children: pages,
        ),

        // body: PreloadPageView.builder(
        //   itemCount: pages.length,
        //   itemBuilder: (context, index) => pages[index],
        //   // onPageChanged: (int position) {...},
        //   preloadPagesCount: 3,
        //   controller: controller,
        // ),

        // body: PageView.builder(
        //   controller: controller,
        //   allowImplicitScrolling: true,
        //   itemCount: pages.length,
        //   itemBuilder: (context, index) => pages[index],
        //   onPageChanged: (pageIndex) {
        //     setState(() {
        //       pageNumber = pageIndex;
        //     });
        //   },
        // ),

        bottomSheet: SizedBox(
          height: 70,
          child: Stack(
            clipBehavior: Clip.none,
            children: [
              Positioned(
                bottom: -50.0,
                left: 0.0,
                right: 0.0,
                height: 50.0,
                child: Container(
                  color: Theme.of(context).scaffoldBackgroundColor,
                  height: 50,
                  width: double.infinity,
                ),
              ),
              Positioned(
                left: 0,
                right: 0,
                bottom: 0,
                height: 70,
                child: Container(
                  color: Colors.transparent,
                  padding: const EdgeInsets.symmetric(horizontal: 30),
                  height: 70,
                  child: Align(
                    alignment: Alignment.center,
                    child: Flex(
                      direction: Axis.horizontal,
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Flexible(
                          flex: 1,
                          child: Visibility(
                            visible: pageNumber != 0,
                            maintainState: true,
                            maintainAnimation: true,
                            maintainSize: true,
                            child: IconButton(
                              onPressed: () => controller.previousPage(
                                  duration: const Duration(milliseconds: 1500),
                                  curve: Curves.fastLinearToSlowEaseIn),
                              icon: const Icon(Icons.west_rounded),
                            ),
                          ),
                        ),
                        Flexible(
                          flex: 3,
                          child: RepaintBoundary(
                            child: SmoothPageIndicator(
                              controller: controller,
                              count: pages.length,
                              effect: const WormEffect(
                                spacing: 16,
                                radius: 10,
                                dotHeight: 10,
                                dotWidth: 10,
                                dotColor: Color(0xFFBDBDBD),
                                activeDotColor: Color(0xffc92a42),
                              ),
                            ),
                          ),
                        ),
                        Flexible(
                          flex: 1,
                          child: IconButton(
                            onPressed: () => controller.nextPage(
                                duration: const Duration(milliseconds: 1500),
                                curve: Curves.fastLinearToSlowEaseIn),
                            icon: const Icon(Icons.east_rounded),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class SimplePage extends StatelessWidget {
  const SimplePage({
    super.key,
    required this.title,
    required this.subtitle,
  });

  final String title;
  final String subtitle;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 16.0),
      child: Flex(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.center,
        direction: Axis.vertical,
        children: [
          const Expanded(
            // flex: 2,
            child: Align(
              alignment: Alignment.bottomCenter,
              child: Padding(
                padding: EdgeInsets.only(
                  bottom: 24.0,
                  left: 40,
                  right: 40,
                ),
                child: FlutterLogo(),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 16.0, bottom: 24.0),
            child: Text(
              title,
              textAlign: TextAlign.center,
              style: const TextStyle(
                fontSize: 28.0,
                fontWeight: FontWeight.w700,
              ),
            ),
          ),
          Expanded(
            flex: 1,
            child: Padding(
              padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 16.0),
              child: Text(
                subtitle,
                textAlign: TextAlign.center,
                style: const TextStyle(fontSize: 19.0),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class Picker extends StatefulWidget {
  const Picker({
    super.key,
    required this.title,
    required this.subtitle,
  });

  final String title;
  final String subtitle;

  @override
  State<Picker> createState() => _PickerState();
}

class _PickerState extends State<Picker> {
  DateTime? _selectedDate;
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 0.0),
      child: Flex(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.center,
        direction: Axis.vertical,
        children: [
          const Padding(
            padding: EdgeInsets.only(
              bottom: 24.0,
              left: 40,
              right: 40,
            ),
            child: FlutterLogo(),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 16.0, bottom: 16.0),
            child: Text(
              widget.title,
              textAlign: TextAlign.center,
              style: const TextStyle(
                fontSize: 20.0,
                fontWeight: FontWeight.w700,
              ),
            ),
          ),
          ConstrainedBox(
            constraints: const BoxConstraints(maxWidth: 550),
            child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 25),
              child: RepaintBoundary(
                child: DatePickerWidget(
                  looping: true,
                  firstDate: DateTime(1980),
                  lastDate: DateTime.now(),
                  initialDate: DateTime(2000),
                  dateFormat: "dd/MMMM/yyyy",
                  onChange: (DateTime newDate, _) {
                    setState(() {
                      _selectedDate = newDate;
                    });
                  },
                  pickerTheme: DateTimePickerTheme(
                    backgroundColor: Colors.transparent,
                    itemTextStyle: const TextStyle(
                      // color: Colors.white,
                      fontSize: 19,
                    ),
                    dividerColor:
                        Theme.of(context).brightness == Brightness.dark
                            ? Colors.white54
                            : null,
                  ),
                ),
              ),
            ),
          ),
          Text("${_selectedDate ?? ''}"),
        ],
      ),
    );
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant