Search code examples
flutterflutter-layout

Flutter - How to add a label that follows the progress position in a LinearProgressIndicator


The title is pretty self explanatory I think.

Basically I need to have a LinearProgressIndicator with a label in the same position as the current progress. Like this:

enter image description here

I suppose I need to use a Stack to create the Text, but how can I position it based on the progress of the bar?


Solution

  • You can use Align widget to align the text in the stack. Use alignment property as Alignment.lerp(Alignment.topLeft, Alignment.topRight, _progressValue); The progress value should be from 0 to 1

    https://dartpad.dev/bbc452ca5e8370bf2fbf48d34d82eb93

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(new MaterialApp(
        debugShowCheckedModeBanner: false,
        home: new MyApp(),
      ));
    }
    
    class MyApp extends StatefulWidget {
      @override
      MyAppState createState() => new MyAppState();
    }
    
    class MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('Slider Demo'),
          ),
          body: new Container(
            color: Colors.blueAccent,
            padding: new EdgeInsets.all(32.0),
            child: new ProgressIndicatorDemo(),
          ),
        );
      }
    }
    
    class ProgressIndicatorDemo extends StatefulWidget {
      @override
      _ProgressIndicatorDemoState createState() =>
          new _ProgressIndicatorDemoState();
    }
    
    class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;
    
      @override
      void initState() {
        super.initState();
        controller = AnimationController(
            duration: const Duration(milliseconds: 2000), vsync: this);
        animation = Tween(begin: 0.0, end: 1.0).animate(controller)
          ..addListener(() {
            setState(() {
              // the state that has changed here is the animation object’s value
            });
          });
        controller.repeat();
      }
    
      @override
      void dispose() {
        controller.stop();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        print(animation.value);
        return new Center(
            child: new Stack(children: <Widget>[
          LinearProgressIndicator(
            value: animation.value,
          ),
          Align(
              alignment :Alignment.lerp(Alignment.topLeft, Alignment.topRight, animation.value),
              child: Text("xxxxxxxxxxxxxxxxa"),
            ),
        ]));
      }
    }