实施物料指南中的“移动步骤进度栏”

时间:2019-03-01 19:37:41

标签: flutter material-design flutter-layout

以前在步进器上有一节的材料设计准则:https://material.io/archive/guidelines/components/steppers.html#steppers-types-of-steps。其中包括各种步进器类型,包括“移动台进度条”:

Mobile step progress bar pattern

Flutter有一个Stepper类,但是记录很少。我将如何实现上面看到的那种步进器?

有一个request for documentation on Github涉及到这个主题,但是到目前为止,还没有关于如何实现此目标的明确指南。

1 个答案:

答案 0 :(得分:1)

我不认为Flutter的步进器类与您正在谈论的步进器相同。这是出于完全不同的目的。

至于您的“步进器”,实际上一个人很简单。我已经完成了两种方法-一种是使用LinearProgressIndicator,另一种是使用简单的渐变,但是您也可以使用custompaint轻松地完成它。

我已将其包含在PageView示例中,因为这似乎就是您在使用它。 flutter gallery pagination example抄袭了一些PageView代码,实际上该页面可能也值得一看。

import 'package:flutter/material.dart';

main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  PageController _pageController = new PageController(initialPage: 0);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: PageView(
          children: <Widget>[
            Center(child: Text("Page 1")),
            Center(child: Text("Page 2")),
            Center(child: Text("Page 3")),
            Center(child: Text("Page 4")),
          ],
          controller: _pageController,
          physics: AlwaysScrollableScrollPhysics(),
        ),
        bottomNavigationBar: Column(
          children: <Widget>[
            Container(
              height: 10,
              margin: EdgeInsets.symmetric(horizontal: 10),
              alignment: Alignment.center,
              child: GradientPageIndicator(
                pageController: _pageController,
                pageCount: 4,
                primaryColor: Colors.blue,
                secondaryColor: Colors.blue.withOpacity(0.2),
              ),
            ),
            Container(
              height: 10,
              margin: EdgeInsets.symmetric(horizontal: 10),
              alignment: Alignment.center,
              child: ProgressPageIndicator(
                pageController: _pageController,
                pageCount: 4,
                primaryColor: Colors.blue,
                secondaryColor: Colors.blue.withOpacity(0.2),
              ),
            ),
          ],
          mainAxisSize: MainAxisSize.min,
        ),
      ),
    );
  }
}

class ProgressPageIndicator extends AnimatedWidget {
  final PageController pageController;

  final int pageCount;

  final Color primaryColor;

  final Color secondaryColor;

  final num height;

  ProgressPageIndicator({
    @required this.pageController,
    @required this.pageCount,
    @required this.primaryColor,
    @required this.secondaryColor,
    this.height = 2.0,
  }) : super(listenable: pageController);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: height,
      child: LinearProgressIndicator(
        backgroundColor: secondaryColor,
        valueColor: Tween(begin: primaryColor, end: primaryColor).animate(kAlwaysCompleteAnimation),
        value: (pageController.page ?? pageController.initialPage) / (pageCount - 1),
      ),
    );
  }
}

class GradientPageIndicator extends AnimatedWidget {
  final PageController pageController;

  final int pageCount;

  final Color primaryColor;

  final Color secondaryColor;

  final num height;

  GradientPageIndicator({
    @required this.pageController,
    @required this.pageCount,
    @required this.primaryColor,
    @required this.secondaryColor,
    this.height = 2.0,
  }) : super(listenable: pageController);

  @override
  Widget build(BuildContext context) {
    double pagePosition = (pageController.page ?? pageController.initialPage) / (pageCount - 1);
    double alignPosition = pagePosition * 2 - 1;

    print("PagePosition: $pagePosition, alignPosition: $alignPosition");

    return Container(
      height: height,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [primaryColor, secondaryColor],
          begin: Alignment(alignPosition - 0.0001, 0),
          end: Alignment(alignPosition + 0.0001, 0),
        ),
      ),
    );
  }
}