我正在参与「启航计划」

前言

在日常的开发中,UI为了让界面愈加吸引人往往会在界面上用到大量的突变色。那么在本文中,咱们将经过几个事例更好的去了解Flutter中突变色的运用。让咱们开端探索Flutter国际中绚丽多彩的突变色作用吧!

源代码:www.aliyundrive.com/s/ogrtF3xM9…

事例一:突变色边框

很多时分,一个简略的边框并不能满意咱们关于界面的美感要求。咱们期望给边框增添一些特殊的作用,让它愈加有目共睹和独特。而正是在这种情况下,突变色边框成为了一个适宜的选择。在Flutter中,完成突变色边框的办法有很多,有简略的,有复杂的。最简略的完成办法呢便是经过两个Container的叠加,例如:

Container(
  height: 48,
  width: 280,
  padding: const EdgeInsets.all(2),
  decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(30),
      gradient: const LinearGradient(
        colors: [Colors.blue, Colors.red],
      )),
  child: Container(
    alignment: Alignment.center,
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(30),
      color: Colors.white,
    ),
    child: const Text(
      '突变色 — Taxze',
      style: TextStyle(
        fontSize: 20,
        fontWeight: FontWeight.bold,
        color: Colors.black,
      ),
    ),
  ),
),

Flutter 与渐变色相关的那些有趣实用的例子

只需求给外层Container加上LinearGradient突变色,然后加上一个padding,这个padding便是边框的粗细,然后将内部的Container背景设置为白色即可。这种办法非常简略。
但是这种办法呢不够灵敏,有局限性,并且可定制性受限,无法对每个边框的突变进行独立设置。所以关于边框的突变,更推荐运用CustomPainter来进行制作。

class GradientBoundPainter extends CustomPainter {
  final List<Color> colors;
  final double width;
  final double height;
  final double strokeWidth;
  const GradientBoundPainter({
    Key? key,
    required this.colors,
    required this.width,
    required this.height,
    this.strokeWidth = 2.0,
  });
  @override
  void paint(Canvas canvas, Size size) {
    //定义矩形的宽高
    final rectWidth = width, rectHeight = height;
    //圆角。必要的话可以将其作为变量传进来
    final radius = 10.0;
    //定义矩形的方位和尺度
    Rect rect = Offset(
        size.width / 2 - rectWidth / 2, size.height / 2 - rectHeight / 2) &
    Size(rectWidth, rectHeight);
    //RRect.fromRectAndRadius一个具有圆角的矩形
    RRect rRect = RRect.fromRectAndRadius(rect, Radius.circular(radius));
    //制作
    final paint = Paint()
    //创立线性突变着色器
      ..shader = LinearGradient(
        begin: Alignment.centerLeft,
        end: Alignment.centerRight,
        colors: colors,
      ).createShader(rect)
      ..strokeWidth = strokeWidth
      //只制作边框而不填充
      ..style = PaintingStyle.stroke;
    canvas.drawRRect(rRect, paint);
  }
  @override
  bool shouldRepaint(covariant GradientBoundPainter oldDelegate) {
    return oldDelegate.colors != colors;
  }
}

运用起来也很简略

Container(
  width: 200,
  height: 48,
  child: LayoutBuilder(
    builder: (BuildContext _, BoxConstraints bc) {
      return CustomPaint(
        painter: GradientBoundPainter(colors: [
          const Color(0xFFFA709A),
          const Color(0xFFFF8D1A),
        ], width: bc.maxWidth, height: bc.maxHeight),
        // child: SizedBox(),
      );
    },
  ),
);

Flutter 与渐变色相关的那些有趣实用的例子

事例二:TabBar突变色指示器

TabBar在开发中是一种常用的组件,用于切换不同的内容或功用模块。而为了增强标签栏的可视作用,让用户在界面切换时获得愈加流畅和有目共睹的体会,市面上的各大app基本上都对TabBar的指示器indicator做了特殊化。而Flutter自带的对indicator款式修改就那么几种,底子不够用啊(连改个长度都要自己自定义)。那么在这个事例中,咱们就来研究下,怎么自定义制作一个突变色的indicator

indicator需求一个Decoration目标,所以咱们首要需求承继于Decoration

class CustomTabIndicator extends Decoration {
}

中心制作逻辑如下

@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
  return _UnderlinePainter(this, onChanged);
}
///决议操控器宽度的办法
Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
  assert(rect != null);
  assert(textDirection != null);
  final Rect indicator = insets.resolve(textDirection).deflateRect(rect);
  // 期望的宽度
  double wantWidth = this.width;
  // 取中心坐标
  double cw = (indicator.left + indicator.right) / 2;
 //这里是中心代码
  //下划线靠左
  // return Rect.fromLTWH(indicator.left,
  //     indicator.bottom - borderSide.width, wantWidth, borderSide.width);
  //下划线居中
  return Rect.fromLTWH(cw - wantWidth / 2,
      indicator.bottom - borderSide.width, wantWidth, borderSide.width);
}
@override
Path getClipPath(Rect rect, TextDirection textDirection) {
  return Path()..addRect(_indicatorRectFor(rect, textDirection));
}
class _UnderlinePainter extends BoxPainter {
  _UnderlinePainter(this.decoration, VoidCallback? onChanged)
      : assert(decoration != null),
        super(onChanged);
  final CustomTabIndicator decoration;
  ///决议操控器边角形状的办法
  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    assert(configuration != null);
    assert(configuration.size != null);
    final Rect rect = offset & configuration.size!;
    final TextDirection textDirection = configuration.textDirection!;
  	//调用 decoration._indicatorRectFor(rect, textDirection) 办法计算出指示器的方位和尺度,
		//并运用 deflate 办法缩小矩形的大小,以便将边框的一半包含在矩形内。
    final Rect indicator = decoration
        ._indicatorRectFor(rect, textDirection)
        .deflate(decoration.borderSide.width / 2.0);
    final gradient = LinearGradient(
      colors: [Color(0xFFFA709A), Color(0xFFFF8C1A)],
      begin: Alignment.centerLeft,
      end: Alignment.centerRight,
    );
    final Paint paint = decoration.borderSide.toPaint()
      ..shader = gradient.createShader(indicator)
      ..strokeCap = decoration.strokeCap; //这块更改为想要的形状
    canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
  }
}

运用起来也很简略:

TabBar(
  controller: controller,
  indicator: const CustomTabIndicator(),
  ...
),

Flutter 与渐变色相关的那些有趣实用的例子


以下是一些有趣的例子

事例三:突变色爆炸粒子

Flutter 与渐变色相关的那些有趣实用的例子

一个会随即生成30个爆炸作用的突变色粒子。

完成起来也很简略,以下是中心的生成逻辑:

//经过定时器调用生成粒子的函数
_timer = Timer.periodic(Duration(milliseconds: 500), (_) {
  _explode();
});
//随机生成粒子
void _explode() {
    final random = Random();
    _particles.clear();
    for (int i = 0; i < 30; i++) {
      final particle = Particle(
      	//色彩
        color: _colors[random.nextInt(_colors.length)],
      	//视点
        angle: random.nextDouble() * 2 * pi,
      	//间隔
        distance: random.nextDouble() * 120,
      	//大小
        size: random.nextDouble() * 8 + 2,
      	//旋转视点
        rotation: random.nextDouble() * 2 * pi,
      );
      _particles.add(particle);
    }
    setState(() {});
}
//渲染
for (final particle in _particles)
    Positioned(
    	//确认粒子在屏幕上的具体方位
      left: particle.distance * cos(particle.angle) +
          MediaQuery.of(context).size.width / 4,
      top: particle.distance * sin(particle.angle) +
          MediaQuery.of(context).size.height / 5,
    	//操控粒子的旋转
      child: Transform.rotate(
        angle: particle.rotation,
        child: Container(
          width: particle.size,
          height: particle.size,
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            gradient: RadialGradient(
              colors: [
                particle.color.withOpacity(1.0),
                particle.color.withOpacity(0.0),
              ],
            ),
          ),
        ),
      ),
    ),

事例四:突变色加载指示器

Flutter 与渐变色相关的那些有趣实用的例子

经过AnimationAnimationController来操控旋转和色彩的改变。

中心逻辑

//将动画操控器与色彩过渡动画进行关联
_animation = _animationController.drive(
  ColorTween(
    begin: Colors.red,
    end: Colors.purple,
  ),
);
AnimatedBuilder(
   animation: _animationController,
   builder: (BuildContext context, Widget? child) {
     return Transform.rotate(
       //操控旋转
       angle: _animationController.value * 2 * pi, 
       child: Container(
         ...
         decoration: BoxDecoration(
           shape: BoxShape.circle,
           //操控突变
           gradient: LinearGradient(
             colors: [
               _animation.value!,
               _animation.value!.withOpacity(0.5),
             ],
             begin: Alignment.topLeft,
             end: Alignment.bottomRight,
           ),
         ),
         child: Icon(...),
       ),
     );
   },
 ),

总结

在本篇文章中,咱们探讨了几个Flutter中突变色的相关事例。Flutter供给了丰富的突变色支持和灵敏的定制选项,使咱们可以轻松完成各种各样的突变色作用。无论是用于背景、文本、图标还是边框,突变色都能为应用程序带来生动、多样和吸引人的视觉作用。期望本篇文章对你理解和运用Flutter中的突变色相关内容有所帮助,激起你的创造力~

关于我

Hello,我是Taxze,如果您觉得文章对您有价值,期望您能给我的文章点个❤️,有问题需求联系我的话:我在这里,也可以经过的新的私信功用联系到我。如果您觉得文章还差了那么点东西,也请经过重视督促我写出更好的文章~万一哪天我进步了呢?