0

This is the code I used to switch between dark mode and light mode. Everything works fine but the color of navigation bar and status bar doesn't change automatically when my widget subtree contains "Sliver App Bar."

Here's the preview

PS: As soon as I remove the Sliver App Bar, everything works fine

.

Code I used to switch between theme.

if (MediaQuery.of(context).platformBrightness == Brightness.light) {
  setState(() {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light.copyWith(
      statusBarColor: Color(0xDCDCDCDC).withOpacity(1),
      statusBarIconBrightness: Brightness.dark,
      systemNavigationBarColor: Color(0xFAFAFAFA),
      systemNavigationBarIconBrightness: Brightness.dark,
    ));
  });
} 
else {
  setState(() {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark.copyWith(
      statusBarColor: Color(0x000).withOpacity(1),
      statusBarIconBrightness: Brightness.light,
      systemNavigationBarColor: Colors.black.withAlpha(234),
      systemNavigationBarIconBrightness: Brightness.light,
    ));
  });
}

.

Code I used for Sliver App Bar

class _HomeScreen extends State<HomeScreen>{
  @override
  Widget build(BuildContext context) {

    return CustomScrollView(
        physics: BouncingScrollPhysics(),
        slivers: <Widget>[
          SliverAppBar(
            title: Text(
              "Home",
              style: Theme.of(context).textTheme.title.copyWith(fontWeight: FontWeight.w600),
            ),
            floating: true,
            backgroundColor: Theme.of(context).primaryColorDark,
            elevation: 3,
            forceElevated: true,
            leading: Padding(
              padding: EdgeInsets.only(
                left: 16,
                top: 10,
                bottom: 10
              ),
              child: ClipOval(
                clipper: ProfileClipper(),
                child: Image.network(
                  'https://images.unsplash.com/photo-1511447333015-45b65e60f6d5?ixlib=rb-1.2.1&w=1000&q=80',
                  fit: BoxFit.cover,
                  loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) {
                    if (loadingProgress == null)
                      return child;
                    return Center(
                      child: CircularProgressIndicator(
                        value: loadingProgress.expectedTotalBytes != null
                            ? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes
                            : null,
                      ),
                    );
                  },
                ),
              ),
            ),
            actions: <Widget>[
              Padding(
                padding: EdgeInsets.only(
                  right: 8
                ),
                child: IconButton(
                  icon: Icon(
                    Icons.more_vert
                  ),
                  onPressed: () {},
                ),
              )
            ],
          ),

        ],
      );
  }
}
Fru2
  • 1
  • 1

3 Answers3

2

You can try add prop: brightness: MediaQuery.of(context).platformBrightness to SliverAppBar?

dangngocduc
  • 1,588
  • 8
  • 13
0

I've taken your code and make some modifications to make it work. I've moved the method that changes the Brightness and colors of your app to the Main Widget, making it stateful. This allows you to easily change the brightness of your whole application, including the status bar. I've also moved the SystemChrome changes to outside of the setState, as they don't need it to be applied. Check the code below, and test it yourself:

class MyApp extends StatefulWidget {
  // This widget is the root of your application.
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Brightness _themeBrightness = Brightness.light;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        brightness: _themeBrightness,
        primarySwatch: Colors.blueGrey,
        appBarTheme: AppBarTheme(
          brightness: _themeBrightness
        ),
      ),
      home: Scaffold(
        body: SliverAppBarTheme60543149(
          swapThemeBrightness: swapThemeBrightness,
        )
      ),
    );
  }

  void swapThemeBrightness(){
    if (_themeBrightness == Brightness.light) {
      SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
        statusBarColor: Colors.black,
        systemNavigationBarColor: Colors.black,
        systemNavigationBarIconBrightness: Brightness.light,
      ));
      setState(() {
        _themeBrightness = Brightness.dark;
      });
    } else {
      SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
        statusBarColor: Colors.white,
        systemNavigationBarColor: Colors.white,
        systemNavigationBarIconBrightness: Brightness.dark,
        systemNavigationBarDividerColor: Colors.white,
      ));
      setState(() {
        _themeBrightness = Brightness.light;
      });
    }
  }
}

class SliverAppBarTheme60543149 extends StatefulWidget {
  final Function swapThemeBrightness;

  SliverAppBarTheme60543149({
    @required this.swapThemeBrightness
  });

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

class _SliverAppBarTheme60543149State extends State<SliverAppBarTheme60543149> {
  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      physics: BouncingScrollPhysics(),
      slivers: <Widget>[
        SliverAppBar(
          title: Text(
            "Home",
            style: Theme.of(context).textTheme.title.copyWith(fontWeight: FontWeight.w600),
          ),
          floating: true,
          backgroundColor: Theme.of(context).primaryColorDark,
          elevation: 3,
          forceElevated: true,
          leading: Padding(
            padding: EdgeInsets.only(
              left: 16,
              top: 10,
              bottom: 10
            ),
            child: Container(
              height: 60,
              width: 60,
              color: Colors.blue,
            ),
          ),
          actions: <Widget>[
            Padding(
              padding: EdgeInsets.only(
                right: 8
              ),
              child: IconButton(
                icon: Icon(
                  Icons.more_vert
                ),
                onPressed: () {},
              ),
            )
          ],
        ),
        SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, int){
              return Padding(
                padding: const EdgeInsets.all(8.0),
                child: RaisedButton(
                  onPressed: widget.swapThemeBrightness,
                  child: Text('Swap theme'),
                ),
              );
            },
            childCount: 1,
          ),
        ),
      ],
    );
  }
}
J. S.
  • 8,905
  • 2
  • 34
  • 44
0

this works with me

SliverAppBar(
iconTheme: IconThemeData(color: Colors.black),
 brightness: Brightness.light,