fluttercommunity / flutter_sticky_headers

Flutter Sticky Headers - Lets you place "sticky headers" into any scrollable content in your Flutter app. No special wrappers or magic required. Maintainer: @slightfoot
https://pub.dev/packages/sticky_headers
MIT License
1.1k stars 129 forks source link

Sticky headers not working after application is resumed - but only if dark theme is configured #77

Open buchen opened 1 year ago

buchen commented 1 year ago

I am facing an issue I cannot wrap my head around:

If the material app has a dark theme configured, then the sticky headers do not work anymore if the application is resumed (for example if the app is closed and reopened). As you can see from the recording, it works as expected if no dark theme is configured. However, just by adding the dark theme (not even using the dark theme), the sticky headers are lost. The header remain at the last position and are not updated anymore when scrolling.

Is anybody facing a similar issue? Does anybody have an idea in which direction I should investigate/debug? At the moment, I do not even know where to look...

https://github.com/fluttercommunity/flutter_sticky_headers/assets/587976/cc3084b8-8333-4539-b9e1-5232c231fdad

This is the example code (it is the simplified example application from sticky headers repository):

import 'package:flutter/material.dart';
import 'package:sticky_headers/sticky_headers.dart';

void main() => runApp(const ExampleApp());

@immutable
class ExampleApp extends StatelessWidget {
  const ExampleApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sticky Headers Example',
      theme: ThemeData(primarySwatch: Colors.amber),
      darkTheme: ThemeData(primarySwatch: Colors.blueGrey),
      home: const Example1(),
    );
  }
}

@immutable
class Example1 extends StatefulWidget {
  const Example1({Key? key}) : super(key: key);

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

class Example1State extends State<Example1> {
  final ScrollController _pageScrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Example 1 - now dark theme configured'),
      ),
      body: ListView.builder(
        controller: _pageScrollController,
        itemCount: 20,
        itemBuilder: (context, index) {
          return StickyHeader(
            controller: _pageScrollController, // Optional
            header: Container(
              height: 60.0,
              color: Colors.blueGrey[700],
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              alignment: Alignment.centerLeft,
              child: Text(
                'Header #$index',
                style: const TextStyle(color: Colors.white),
              ),
            ),
            content: Container(
              color: Colors.grey[300],
              child: SizedBox(
                height: 200.0,
                child: Center(
                  child: Text('Content #$index'),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}
Output of flutter doctor (Flutter, stable, 3.10.5) ``` [✓] Flutter (Channel stable, 3.10.5, on macOS 13.4 22F66 darwin-arm64, locale de-DE) • Flutter version 3.10.5 on channel stable at /Users/asbn/Tools/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 796c8ef792 (7 days ago), 2023-06-13 15:51:02 -0700 • Engine revision 45f6e00911 • Dart version 3.0.5 • DevTools version 2.23.1 [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/asbn/Library/Android/sdk • Platform android-33, build-tools 33.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 14.3.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14E300c • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2022.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694) [✓] VS Code (version 1.79.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.66.0 ```
buchen commented 1 year ago

BTW, for the time being, I am listening to to the app lifecycle events and explicitly set the state after a resume event:

class _SomeState extends State<SomeStatefulWidget>
    with WidgetsBindingObserver {

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  [...]

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.resumed) {
      setState(() {});
    }
  }
}