Реализация «Мобильного шага прогресса» из материалов руководства - PullRequest
0 голосов
/ 01 марта 2019

В руководящих указаниях по проектированию материалов использовался раздел на степперах: https://material.io/archive/guidelines/components/steppers.html#steppers-types-of-steps.Это включало различные типы степперов, в том числе «Индикатор шага мобильного шага»:

Mobile step progress bar pattern

Flutter имеет класс Stepper, но очень скудно документирован.Как бы я реализовал вид степпера, показанный выше?

Есть запрос на документацию по Github , который затрагивает эту тему, но пока нет четких руководств по тому, какреализовать это.

1 Ответ

0 голосов
/ 02 марта 2019

Я не думаю, что класс степпера Флаттера - это тот же самый степпер, о котором вы говорите.Он предназначен для совершенно другой цели.

Что касается вашего "степпера", на самом деле сделать его самостоятельно довольно просто.Я сделал это двумя способами - один с помощью LinearProgressIndicator, а другой - с простым градиентом, но вы также можете сделать это довольно просто с помощью пользовательской краски.

Я включил это в пример PageView, как кажетсябыть тем, что ты делаешь с этим.Часть кода 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),
        ),
      ),
    );
  }
}
...