【问题标题】:ShaderMask LinearGradient's stops strange behaviorShaderMask LinearGradient 停止奇怪的行为
【发布时间】:2020-01-12 16:31:00
【问题描述】:

我想淡化内容的两侧(边缘)。

我使用ShaderMaskLinearGradient,效果很好,只是我不明白为什么我的stops 没有正确居中,我使用stops: [0.0, 0.05, 0.95, 1.0] 以便它应该褪色0.05在每一侧,但我得到以下信息(我添加了一个具有相同配置的 Container 渐变以进行比较):

带调试绘制模式:

我对@9​​87654331@ 和ShaderMask 使用完全相同的停靠点,但得到不同的结果。

当然,我可以为ShaderMask 渐变尝试不同的stops 值,直到我把它居中,但这似乎是一个hack。

谁能解释一下?

如果有人想试一试,这里是代码:

return Container(
  height: 200,
  child: Column(
    children: <Widget>[
      Expanded(
        child: ShaderMask(
          blendMode: BlendMode.modulate,
          shaderCallback: (Rect bounds) {
            return LinearGradient(
              begin: Alignment.centerLeft,
              end: Alignment.centerRight,
              colors: <Color>[Colors.transparent, Colors.white, Colors.white, Colors.transparent],
              stops: [0.0, 0.05, 0.95, 1.0],
              tileMode: TileMode.clamp,
            ).createShader(bounds);
          },
          child: Container(
            color: Colors.blue,
            child: ListView(
              children: <Widget>[
                Text(
                  "I'm a ShaderMask and I don't understand why my gradient don't behave like container's gradient. I'm a ShaderMask and I don't understand why my gradient don't behave like container's gradient.",
                  textAlign: TextAlign.justify,
                )
              ],
            ),
          ),
        ),
      ),
      Expanded(
        child: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              begin: Alignment.centerLeft,
              end: Alignment.centerRight,
              colors: [Colors.transparent, Colors.blue, Colors.blue, Colors.transparent],
              stops: [0.0, 0.05, 0.95, 1.0],
              tileMode: TileMode.clamp,
            ),
          ),
          child: ListView(
            children: <Widget>[
              Text(
                "I'm a Container and I don't understand why ShaderMask's gradient don't behave like mine. I'm a Container and I don't understand why ShaderMask's gradient don't behave like mine.",
                textAlign: TextAlign.justify,
              )
            ],
          ),
        ),
      )
    ],
  ),
);

我使用 FractionalOffset 而不是 Alignment.centerRightAlignment.centerRight 得到了相同的结果。

【问题讨论】:

  • createShader(Offset.zero &amp; bounds.size) 或将bounds 向左平移bounds.left 并向上平移bounds.top
  • 是的好技巧,它解决了问题,谢谢。我的想法是在ShaderMask 小部件中应该有一个选项,以便我们可以设置Rect 偏移量。
  • 这不是技巧,基本上传递给shaderCallbackbounds 是在全局坐标中,而您必须将本地Rect 传递给createShader 方法
  • 好的,我明白了,所以我可以使用 createShader(Rect.fromLTRB(0, 0, bounds.width, bounds.height)) 来做同样的事情。谢谢,只需添加一个带有解释的答案,以便我接受。
  • 是的,完全一样 - 但我认为Offset.zero &amp; bounds.size 更...嗯,复杂吗? ;-) 随意写一个自我答案

标签: flutter dart flutter-layout


【解决方案1】:

shaderCallback 为给定的Rect 创建一个Shader,并且Rect 坐标相对于给定的origin

着色器回调以子级的当前大小调用,以便它可以根据子级的大小和位置自定义着色器。

这意味着我们必须根据没有偏移的子窗口小部件的大小创建带有Rect 的着色器(基本上传递给shaderCallback 的边界在全局坐标中,而createShader 正在等待本地@ 987654328@)。

所以一个简单的解决方案是创建一个新的Rect,它具有正确的原点(偏移量)和边界:createShader(Rect.fromLTRB(0, 0, bounds.width, bounds.height))

或者更性感的速记:createShader(Offset.zero &amp; bounds.size)

shaderCallback: (Rect bounds) {
  return LinearGradient(
    begin: Alignment.centerLeft,
    end: Alignment.centerRight,
    colors: <Color>[Colors.transparent, Colors.blue, Colors.blue, Colors.transparent],
    stops: [0.0, 0.04, 0.96, 1.0],
    tileMode: TileMode.clamp,
  ).createShader(Offset.zero & bounds.size);
},

感谢pskink!

【讨论】:

    猜你喜欢
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多