flutter 圆角进度条

Flutter框架提供了Material Design风格的线性进度条(LinearProgressIndicator)组件,就是下面的样子,方方正正的,一点也不圆润。
在这里插入图片描述
但是很多APP的设计都按照Material Design风格来玩的,各种各样的都有,我们选择最常见的一种来看一下,下面是“淘宝APP->淘抢购”页面里面的进度条,还是带动画的。

如果直接用线性进度条(LinearProgressIndicator)组件去做,是没办法实现上面的进度条的。正常的话会遇到下面几个问题:

  • List item
  • 没有参数可以设置圆角
  • 组件自带的动画效果是无限循环的
  • 设置了value参数就没有动画效果
  • 没有参数可以设置高度
  • 没有参数可以设置中间的文本组件

但是上面的问题都可以被解决,下面就是具体的解决方案了。

方法一:

设置圆角

为进度条设置圆角边框的方法就是圆角矩形剪裁(ClipRRect)组件,用圆角矩形剪裁(ClipRRect)组件把线性进度条(LinearProgressIndicator)组件包装起来就可以了。

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo 主页'),
      ),
      // 圆角矩形剪裁(`ClipRRect`)组件,使用圆角矩形剪辑其子项的组件。
      body: ClipRRect(
        // 边界半径(`borderRadius`)属性,圆角的边界半径。
        borderRadius: BorderRadius.all(Radius.circular(10.0)),
        child: LinearProgressIndicator(
          value: 0.6,
          backgroundColor: Color(0xffFFE3E3),
          valueColor: AlwaysStoppedAnimation<Color>(Color(0xffFF4964)),
        ),
      ),
    );
  }
}

在这里插入图片描述

设置高度与宽度

为进度条添加高度与宽度限制的方法也不难,就是用大小框(SizedBox)组件包装线性进度条(LinearProgressIndicator)组件。
在这里插入图片描述

设置内容文本

为进度条的里面配置描述文本,和上面一样,就是继续包装(PS:Flutter的布局方式真的是过度包装),用堆栈(Stack)组件包装线性进度条(LinearProgressIndicator)组件。

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo 主页'),
      ),
      body: Stack(
        children: <Widget>[
          SizedBox(
            height: 10.0,
            width: 98.0,
            // 圆角矩形剪裁(`ClipRRect`)组件,使用圆角矩形剪辑其子项的组件。
            child: ClipRRect(
              // 边界半径(`borderRadius`)属性,圆角的边界半径。
              borderRadius: BorderRadius.all(Radius.circular(10.0)),
              child: LinearProgressIndicator(
                value: 0.6,
                backgroundColor: Color(0xffFFE3E3),
                valueColor: AlwaysStoppedAnimation<Color>(Color(0xffFF4964)),
              ),
            ),
          ),
          Container(
            height: 10.0,
            width: 98.0,
            padding: EdgeInsets.only(left: 7.0),
            alignment: Alignment.centerLeft,
            child: Text(
              '已抢60%',
              style: TextStyle(
                color: Color(0xffFFFFFF),
                fontSize: 8.0,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

在这里插入图片描述

设置动画效果

要为进度条设置动画效果,就不得不提到动画控制器(AnimationController)和补间(Tween)组件,Flutter中的大部分动画效果都可以用它们实现。具体怎么使用它们,请参考下面的代码。

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  /// 当前的进度。
  double currentProgress = 0.6;
  // 动画相关控制器与补间。
  AnimationController animation;
  Tween<double> tween;

  @override
  void initState() {
    // AnimationController({
    //   double value,
    //   Duration duration,
    //   String debugLabel,
    //   double lowerBound: 0.0,
    //   double upperBound: 1.0,
    //   TickerProvider vsync
    // })
    // 创建动画控制器
    animation = AnimationController(
      // 这个动画应该持续的时间长短。
      duration: const Duration(milliseconds: 900),
      vsync: this,
      // void addListener(
      //   VoidCallback listener
      // )
      // 每次动画值更改时调用监听器
      // 可以使用removeListener删除监听器
    )..addListener(() {
        setState(() {});
      });
    // Tween({T begin, T end }):创建tween(补间)
    tween = Tween<double>(
      begin: 0.0,
      end: currentProgress,
    );
    // 开始向前运行这个动画(朝向最后)
    animation.forward();
    super.initState();
  }

  @override
  void dispose() {
    animation.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO:构建页面的主要内容。
  }
}

在上面的代码中,我们已经设置好了动画与补间,下面就把线性进度条(LinearProgressIndicator)组件中的value属性值设置成动画控制。

    // TODO:构建页面的主要内容。
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo 主页'),
      ),
      body: Stack(
        children: <Widget>[
          SizedBox(
            height: 10.0,
            width: 98.0,
            // 圆角矩形剪裁(`ClipRRect`)组件,使用圆角矩形剪辑其子项的组件。
            child: ClipRRect(
              // 边界半径(`borderRadius`)属性,圆角的边界半径。
              borderRadius: BorderRadius.all(Radius.circular(10.0)),
              child: LinearProgressIndicator(
                // Animation<T> animate(
                //   Animation<double> parent
                // )
                // 返回一个由给定动画驱动的新动画,但它承担由该对象确定的值
                value: tween.animate(animation).value,
                backgroundColor: Color(0xffFFE3E3),
                valueColor: AlwaysStoppedAnimation<Color>(Color(0xffFF4964)),
              ),
            ),
          ),
          Container(
            height: 10.0,
            width: 98.0,
            padding: EdgeInsets.only(left: 7.0),
            alignment: Alignment.centerLeft,
            child: Text(
              '已抢${(currentProgress * 100).toInt()}%',
              style: TextStyle(
                color: Color(0xffFFFFFF),
                fontSize: 8.0,
                fontFamily: 'PingFangRegular',
              ),
            ),
          ),
        ],
      ),
    );

这样进度条在构建时就会开始播放前进动画了。

方法二:

///横向进度条
  Widget _LinearProgressIndicator(int attendance, int total) {
    double lineW = 0;
    if (total != 0) {// 81  是左右边距之和
      lineW = (ScreenUtil.screenWidth - 81) * attendance / total;
    }
    return Container(
      margin: EdgeInsets.only(left: 41, right: tyW(40), top: 68),
      child: Stack(
        children: <Widget>[
          Container(
            height: tyW(4),
            decoration: new BoxDecoration(
              color: KColorConstant.ffe8e9eb,
              borderRadius: new BorderRadius.circular((2)), // 圆角度
            ),
          ),
          Positioned(
            left: 0,
            child: Container(
              width: lineW,
              height: 4,
              decoration: new BoxDecoration(
                color: KColorConstant.ff2b78d6,
                borderRadius: new BorderRadius.circular((2)), // 圆角度
              ),
            ),
          )
        ],
      ),
    );
  }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值