web-dev-qa-db-fra.com

Flutter Comment vérifier si Sliver AppBar est développé ou réduit?

J'utilise un SliverAppBar dans Flutter, avec un widget d'arrière-plan.

Le truc c'est quand c'est développé, le titre et les icônes (en tête et actions) doivent être blanc pour être vu correctement, et quand c'est collapsed, ils doivent être remplacés par noir.

Des idées sur la façon dont je peux en tirer un bool ? Ou d'autres façons de résoudre ce problème.

Merci.

class SliverExample extends StatefulWidget {
  final Widget backgroundWidget;
  final Widget bodyWidgets;

  SliverExample({
    this.backgroundWidget,
    this.body,
  });
  @override
  _SliverExampleState createState() => _SliverExampleState();
}

class _SliverExampleState extends State<SliverExample> {

  // I need something like this
  // To determine if SliverAppBar is expanded or not.
  bool isAppBarExpanded = false;

  @override
  Widget build(BuildContext context) {

    // To change the item's color accordingly
    // To be used in multiple places in code
    Color itemColor = isAppBarExpanded ? Colors.white : Colors.black;

    // In my case PrimaryColor is white,
    // and the background widget is dark

    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            pinned: true,
            leading: BackButton(
              color: itemColor, // Here
            ),
            actions: <Widget>[
              IconButton(
                icon: Icon(
                  Icons.shopping_cart,
                  color: itemColor, // Here
                ),
                onPressed: () {},
              ),
            ],
            expandedHeight: 200.0,
            flexibleSpace: FlexibleSpaceBar(
              centerTitle: true,
              title: Text(
                'title',
                style: TextStyle(
                  fontSize: 18.0,
                  color: itemColor, // Here
                ),
              ),
              // Not affecting the question.              
              background: widget.backgroundWidget,
            ),
          ),
          // Not affecting the question.
          SliverToBoxAdapter(child: widget.body),
        ],
      ),
    );
  }
}
7
Sina Seirafi

Vous pouvez utiliser LayoutBuilder pour obtenir la plus grande hauteur de ruban AppBar. Lorsque le plus grand.hauteur = 80,0, cela signifie en fait que la barre d'application du ruban est réduite.

Voici un exemple complet:

import 'package:flutter/material.Dart';

void main() => runApp(MaterialApp(
      home: MyApp(),
    ));

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var top = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[
          SliverAppBar(
              expandedHeight: 200.0,
              floating: false,
              pinned: true,
              flexibleSpace: LayoutBuilder(
                  builder: (BuildContext context, BoxConstraints constraints) {
                // print('constraints=' + constraints.toString());
                top = constraints.biggest.height;
                return FlexibleSpaceBar(
                    centerTitle: true,
                    title: AnimatedOpacity(
                        duration: Duration(milliseconds: 300),
                        //opacity: top == 80.0 ? 1.0 : 0.0,
                        opacity: 1.0,
                        child: Text(
                          top.toString(),
                          style: TextStyle(fontSize: 12.0),
                        )),
                    background: Image.network(
                      "https://images.unsplash.com/photo-1542601098-3adb3baeb1ec?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=5bb9a9747954cdd6eabe54e3688a407e&auto=format&fit=crop&w=500&q=60",
                      fit: BoxFit.cover,
                    ));
              })),
        ];
      },body: ListView.builder(
        itemCount: 100,
        itemBuilder: (context,index){
          return Text("List Item: " + index.toString());
        },
      ),
    ));
  }
}

Résultat final:

enter image description here

13
Jack Sun

Vous devez utiliser ScrollController pour obtenir l'effet souhaité

essayez ce code

import 'package:flutter/material.Dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SliverExample(
        bodyWidgets: Text(
            'Hello Body gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg'),
        backgroundWidget: Text('Hello Background'),
      ),
    );
  }
}

class SliverExample extends StatefulWidget {
  final Widget backgroundWidget;
  final Widget bodyWidgets;

  SliverExample({
    this.backgroundWidget,
    this.bodyWidgets,
  });

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

class _SliverExampleState extends State<SliverExample> {

  ScrollController _scrollController;
  Color _theme ;

  @override
  void initState() {
    super.initState();
    _theme = Colors.black;

    _scrollController = ScrollController()
      ..addListener(
        () => _isAppBarExpanded ?
            _theme != Colors.white ?
        setState(
          () {
            _theme = Colors.white;
            print(
                'setState is called');
          },
        ):{}
            : _theme != Colors.black ?
        setState((){
          print(
              'setState is called');
          _theme = Colors.black;
        }):{},

      );
  }

  bool get _isAppBarExpanded {
    return _scrollController.hasClients &&
        _scrollController.offset > (200 - kToolbarHeight);
  }

  @override
  Widget build(BuildContext context) {
    // To change the item's color accordingly
    // To be used in multiple places in code
    //Color itemColor = isAppBarExpanded ? Colors.white : Colors.black;

    // In my case PrimaryColor is white,
    // and the background widget is dark

    return Scaffold(
      body: CustomScrollView(
        controller: _scrollController,
        slivers: <Widget>[
          SliverAppBar(
            pinned: true,
            leading: BackButton(
              color: _theme, // Here
            ),
            actions: <Widget>[
              IconButton(
                icon: Icon(
                  Icons.shopping_cart,
                  color: _theme, // Here
                ),
                onPressed: () {},
              ),
            ],
            expandedHeight: 200.0,
            flexibleSpace: FlexibleSpaceBar(
              centerTitle: true,
              title: Text(
                'title',
                style: TextStyle(
                  fontSize: 18.0,
                  color: _theme, // Here
                ),
              ),
              // Not affecting the question.
              background: widget.backgroundWidget,
            ),
          ),
          // Not affecting the question.
          SliverToBoxAdapter(child: widget.bodyWidgets),
        ],
      ),
    );
  }
}

si vous ne connaissez pas? : notation vous pouvez utiliser ce qui suit

_scrollController = ScrollController()
      ..addListener(
          (){
            if(_isAppBarExpanded){
              if(_theme != Colors.white){
                setState(() {
                  _theme = Colors.white;
                  print('setState is called with white');
                });
              }
            }else{
              if(_theme != Colors.black){
                setState(() {
                  _theme = Colors.black;
                  print('setState is called with black');
                });
              }
            }
          }
6
Saed Nabil