Flutter系列之自定义实现圆角渐变进度条

flutter SDK提供的ProgressIndicator不支持圆角属性的设置,看起来不是很美观,系统自带的LinearProgressIndicator是这样的:

这样的进度条显然无法满足UI设计师的要求,既然系统提供的进度条不支持圆角和渐变,那我们只能通过自定义view来实现了。

先来看一下实现的效果:

flutter是如何自定义view的呢,

flutter提供两个类来实现自定义view

  • CustomPaint :在绘制阶段提供一个 Canvas 画布
  • CustomPainter : 可以设置画笔的颜色、粗细、是否抗锯齿、笔触形状以及作画风格等

下面就用这两个类的使用来实现一个渐变的圆角进度条

import 'package:flutter/material.dart';

class GradientLinearProgressBar extends StatelessWidget {

  final double strokeWidth;//画笔的宽度,其实是进度条的高度
  final bool strokeCapRound;//是否需要圆角
  final double value;//进度值
  final Color backgroundColor;//进度条背景色
  final List<Color> colors;//渐变的颜色列表

  GradientLinearProgressBar({
    this.strokeWidth = 2.0,
    @required this.colors,
    this.value,
    this.backgroundColor = const Color(0xFFEEEEEE),
    this.strokeCapRound = false
  });

  @override
  Widget build(BuildContext context) {
    var _colors = colors;
    if (_colors == null) {
      Color color = Theme.of(context).accentColor;
      _colors = [color, color];
    }
    return CustomPaint(
      size: MediaQuery.of(context).size,
      painter: _GradientLinearProgressPainter(
        strokeWidth: strokeWidth,
        strokeCapRound: strokeCapRound,
        backgroundColor: backgroundColor,
        value: value,
        colors: _colors
      ),
    );
  }
}

class _GradientLinearProgressPainter extends CustomPainter{

  final double strokeWidth;
  final bool strokeCapRound;
  final double value;
  final Color backgroundColor;
  final List<Color> colors;
  final List<double> stops;
  final p = Paint();

  _GradientLinearProgressPainter({
    this.strokeWidth = 2.0,
    @required this.colors,
    this.value = 0.0,
    this.backgroundColor = const Color(0xFFEEEEEE),
    this.strokeCapRound = false,
    this.stops
  });

  @override
  void paint(Canvas canvas, Size size) {
    p.strokeCap = strokeCapRound ? StrokeCap.round : StrokeCap.butt;
    p.style = PaintingStyle.fill;
    p.isAntiAlias = true;
    p.strokeWidth = strokeWidth;

    double _offset = strokeWidth / 2;//留一定的偏移量
    var start = Offset(_offset, _offset);//画笔起点坐标
    var end = Offset(size.width, _offset);//画笔终点坐标

    if (backgroundColor != Colors.transparent) {
      p.color = backgroundColor;
      canvas.drawLine(start, end, p);
    }

    if (value > 0) {
      var valueEnd = Offset(value * size.width + _offset, _offset);//计算进度的长度
      Rect rect = Rect.fromPoints(start, valueEnd);
      p.shader = LinearGradient(colors: colors, stops: stops).createShader(rect);
      p.color = Colors.amber;
      canvas.drawLine(start, valueEnd, p);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;

}

自定义view最主要的是继承CustomPainter,实现paint方法。

自定义组件完成以后,使用就很简单了,直接放到widget树中即可

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('圆角渐变进度条'),
      ),
      body: Center(
        child: Container(
          width: 300,
          height: 200,
          child: GradientLinearProgressBar(
            strokeCapRound: true,
            strokeWidth: 10,
            colors: [Color(0xfffff7d7), Colors.blueAccent],
            backgroundColor: Colors.transparent,
            value: progress / 100,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => updateProgress(),
        child: Icon(
          Icons.add
        ),
      ),
    );

 

 

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值