【问题标题】:Does anyone know how to add a gradient background to CupertinoSliverAppBar?有谁知道如何向 Cupertino SliverAppBar 添加渐变背景?
【发布时间】:2019-09-27 01:42:09
【问题描述】:

我正在尝试在 Flutter 应用程序中为 CupertinoSliverAppBar 添加渐变背景,但我似乎无法弄清楚如何去做。 SliverAppBar 有一个flexibleSpace 属性可以接受渐变,但CupertinoSliverAppBar 只有一个backgroundColor 属性。

或者,如果可以将flexibleSpace 中的标题向左移动,我可以这样做。但我也想不通。

我读过这些:

这个问题在 Flutter 存储库中打开:https://github.com/flutter/flutter/issues/25144

@rmtmckenzie 成功了!值得注意的是,这也适用于CupertinoSliverNavigationBar。此外,除了您将看到 backgroundColor 属性被动画化的背景之外,所有的过渡动画都将被保留。您可以通过使用其中一种渐变颜色作为backgroundColor 来作弊,但这并不完美。渐变确实呈现在内容下方。见下文:

【问题讨论】:

  • @rmtmckenzie 有什么想法吗?
  • pub.dev/packages/gradientscaffoldwidget CupertinoPageGradientScaffold 方法。
  • 另外,我想知道我们是否可以为 Cupertino sliver 导航栏添加图像背景?有人吗?
  • @NithinSai 我为此创建了一个 PR(和渐变):github.com/flutter/flutter/pull/33177。它仍然需要一些清理才能通过测试
  • @Benjamin 这是个好主意!谢谢

标签: dart flutter flutter-cupertino


【解决方案1】:

这实际上有点困难 - 正如你提到的 CupertinoSliverAppBar 不支持 'flexibleSpace' 或类似的东西,所以你被困在尝试使用也不能满足你需要的背景颜色。

我建议在 Flutter 存储库上打开一个问题,说明这是不可能的以及您为什么要这样做。他们可能不会立即对此采取行动,但如果他们知道人们愿意这样做,它可能会发生。

但并非所有希望立即修复,我们可以作弊! (虽然我希望您在编写版本时使用不那么丑陋的渐变)

我所做的是继承边框,然后覆盖它绘制的内容,以便在绘制实际边框之前绘制你传入的渐变。这是有效的,因为它被赋予了一个覆盖整个应用栏的绘制上下文,并在应用栏的背景上绘制,但在其内容下方(希望 - 它似乎至少在标题下方,所以我认为它也在其他所有内容下方)。背景颜色仍绘制在应用栏下方,因此如果您的渐变有点透明,您可能需要将 backgroundColor 设置为 Colors.transparent。

代码如下:

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

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

class GradientCheatingBorder extends Border {
  const GradientCheatingBorder({
    this.gradient,
    BorderSide top = BorderSide.none,
    BorderSide right = BorderSide.none,
    BorderSide bottom = BorderSide.none,
    BorderSide left = BorderSide.none,
  }) : super(top: top, right: right, bottom: bottom, left: left);

  const GradientCheatingBorder.fromBorderSide(BorderSide side, {this.gradient})
      : super.fromBorderSide(side);

  factory GradientCheatingBorder.all({
    Color color = const Color(0xFF000000),
    double width = 1.0,
    BorderStyle style = BorderStyle.solid,
    Gradient gradient,
  }) {
    final BorderSide side =
        BorderSide(color: color, width: width, style: style);
    return GradientCheatingBorder.fromBorderSide(side, gradient: gradient);
  }

  final Gradient gradient;

  @override
  void paint(
    Canvas canvas,
    Rect rect, {
    TextDirection textDirection,
    BoxShape shape = BoxShape.rectangle,
    BorderRadius borderRadius,
  }) {
    if (gradient != null) {
      canvas.drawRect(
        rect,
        Paint()
          ..shader = gradient.createShader(rect)
          ..style = PaintingStyle.fill,
      );
    }

    super.paint(
      canvas,
      rect,
      textDirection: textDirection,
      shape: shape,
      borderRadius: borderRadius,
    );
  }
}

class GradientAppBar extends StatefulWidget {
  @override
  _GradientAppBarState createState() => _GradientAppBarState();
}

class _GradientAppBarState extends State<GradientAppBar> {
  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      home: CustomScrollView(
        slivers: <Widget>[
          CupertinoSliverNavigationBar(
            largeTitle: Text("Title"),
            border: GradientCheatingBorder.fromBorderSide(
              BorderSide.none,
              gradient: LinearGradient(colors: [Colors.black, Colors.white]),
            ),
          ),
          SliverList(
            delegate: SliverChildListDelegate(
              [
                Container(
                  color: Colors.blue,
                  height: 500,
                ),
                Divider(),
                Container(
                  color: Colors.black12,
                  height: 500,
                ),
                Divider(),
                Container(
                  color: Colors.lightBlue,
                  height: 500,
                ),
                Divider(),
                Container(
                  color: Colors.lightGreen,
                  height: 500,
                ),
                Divider(),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

【讨论】:

  • 它可能很丑,但它非常聪明!谢谢!
【解决方案2】:

你可以试试这个

flexibleSpace: Container(
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.centerLeft,
                end: Alignment.centerRight,
                colors: [
                  Colors.red,
                  Colors.blue
                ],
              ),
            ),
          ),

【讨论】:

  • CupertinoSliverNavigationBar 中没有灵活空间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-25
  • 1970-01-01
  • 2023-03-08
  • 2021-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多