Flutter 如何创建 appbar 看起来像这样,图标可以改变颜色

Flutter how to create appbar look like this, that the icon can change color

我想创建一个像这样的应用栏。我一直在尝试使用 sliverappbar 并且当背景改变不透明度时我无法改变颜色。当我向下滚动时,我想创建一个看起来像这样的应用栏

一直在尝试搜索更多相关的sliverappbar,或者相关的仍然没有找到如何创建它

这是我一直在尝试做的事情

CustomScrollView(
        physics: const BouncingScrollPhysics(
          parent: AlwaysScrollableScrollPhysics(),
        ),
        slivers: <Widget>[
          SliverAppBar(
            title: Container(
              child: Row(
                children: [
                  Expanded(
                    child: Container(
                      decoration: BoxDecoration(
                          color: Colors.white,
                          border: Border.all(color: Colors.grey),
                          borderRadius: BorderRadius.circular(5)),
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Row(
                          children: [
                            Icon(
                              Icons.search,
                              size: 15,
                              color: Colors.grey,
                            ),
                            Text(
                              'Cari di Toki',
                              style: TextStyle(
                                color: Colors.grey,
                                fontSize: 15,
                              ),
                            )
                          ],
                        ),
                      ),
                    ),
                  )
                ],
              ),
            ),
            leading: Container(
              decoration: BoxDecoration(
                  color: Colors.black.withOpacity(0.3),
                  borderRadius: BorderRadius.circular(50)),
              child: Icon(Icons.arrow_back, color: Colors.white),
            ),
            pinned: _pinned,
            snap: _snap,
            floating: _floating,
            stretch: true,
            expandedHeight: 350,
            backgroundColor: Colors.white,
            iconTheme: IconThemeData(color: Colors.black),
            flexibleSpace: FlexibleSpaceBar(
              stretchModes: [StretchMode.zoomBackground],
              centerTitle: true,
              background: Image.network(
                widget.product.imageUrl,
                fit: BoxFit.cover,
              ),
            ),
            actions: [
              Consumer<WishlistProvider>(builder: (context, wp, _) {
                return Badge(
                  toAnimate: true,
                  animationType: BadgeAnimationType.slide,
                  position: BadgePosition.topEnd(top: 5, end: 7),
                  badgeContent: Text(wp.wishListList.length.toString()),
                  child: Container(
                    decoration: BoxDecoration(
                        color: Colors.black.withOpacity(0.3),
                        borderRadius: BorderRadius.circular(50)),
                    child: IconButton(
                      onPressed: () {
                        Navigator.of(context)
                            .pushNamed(WishListScreen.routeName);
                      },
                      icon: const Icon(Icons.favorite, color: Colors.white),
                    ),
                  ),
                );
              }),
              SizedBox(width: 3),
              Consumer<CartProvider>(builder: (context, cp, _) {
                return Badge(
                  toAnimate: true,
                  animationType: BadgeAnimationType.slide,
                  position: BadgePosition.topEnd(top: 5, end: 7),
                  badgeContent: Text(cp.cartlist.length.toString()),
                  child: Container(
                    decoration: BoxDecoration(
                        color: Colors.black.withOpacity(0.3),
                        borderRadius: BorderRadius.circular(50)),
                    child: IconButton(
                      onPressed: () {
                        Navigator.of(context).pushNamed(CartScreen.routeName);
                      },
                      icon:
                          const Icon(Icons.shopping_cart, color: Colors.white),
                    ),
                  ),
                );
              }),
            ],
          ),
          SliverToBoxAdapter(
            child: SizedBox(
              height: 20,
              child: Text(
                widget.product.title,
                style: TextStyle(color: Colors.black),
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  color: index.isOdd ? Colors.white : Colors.black12,
                  height: 100.0,
                  child: Center(
                    child: Text('$index', textScaleFactor: 5),
                  ),
                );
              },
              childCount: 20,
            ),
          ),
        ],
      ),

您可以听取 ScrollController 的偏移量并基于它更新您的应用栏颜色。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const App(),
    );
  }
}

const startColor = Colors.transparent;
const targetColor = Colors.red;

const startIconColor = Colors.red;
const targetIconColor = Colors.white;

class App extends StatefulWidget {
  const App({Key? key}) : super(key: key);

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

class _AppState extends State<App> {
  final scrollController = ScrollController();

  final appBarColorTween = ColorTween(begin: startColor, end: targetColor);
  final iconColorTween = ColorTween(begin: startIconColor, end: targetIconColor);

  double lerp = 0.0; 
  Color get appBarColor => appBarColorTween.transform(lerp) ?? startColor;
  Color get iconColor => iconColorTween.transform(lerp) ?? startIconColor;

  @override
  void initState() {
    scrollController.addListener(listener);
    super.initState();
  }

  @override
  void dispose() {
    scrollController.removeListener(listener);
    super.initState();
  }

  void listener() {
    var offset = scrollController.offset;
    setState(() => lerp = offset < 300 ? offset / 300 : 1);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0.0,
        backgroundColor: appBarColor,
        leading: Icon(Icons.backspace, color: iconColor),
      ),
      extendBodyBehindAppBar: true,
      body: ListView.builder(
        controller: scrollController,
        itemCount: 100,
        itemBuilder: (context, index) {
          return Card(
            margin: const EdgeInsets.all(5),
            child: Container(
              color: Colors.blue[100 * (index % 9 + 1)],
              height: 80,
              alignment: Alignment.center,
              child: Text(
                "Item $index",
                style: const TextStyle(fontSize: 30),
              ),
            ),
          );
        },
      ),
    );
  }
}