如何在flutter中创建自定义步进器?

问题描述 投票:0回答:5

我想在 flutter 中创建这种类型的步进器

到目前为止我已经尝试过这两种方式

Widget get stepper =>
      Container(
          padding: EdgeInsets.all(15),
          color: Colors.white,
          child: ListView.builder(
              itemCount: stepperLIst.length,
              shrinkWrap: true,
              physics: NeverScrollableScrollPhysics(),
              itemBuilder: (context, position) {
                return IntrinsicHeight(
                  child: Container(
                    margin: const EdgeInsets.only(bottom: 20),
                    child: Row(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Column(
                            mainAxisSize: MainAxisSize.min,
                            verticalDirection: VerticalDirection.down,
                            children: [
                              Image.asset(stepperLIst[position].iconName),
                              SizedBox(height: 10),
                              CustomPaint(painter: LineDashedPainter(lineColor: Colors.grey))

                            ],
                          ),
                          SizedBox(width: 10),
                          Expanded(
                            child: Column(
                              mainAxisSize: MainAxisSize.min,
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text(
                                  stepperLIst[position].tittle,
                                  style: BaseStyles.textStyle.copyWith(fontFamily: BaseFonts.bold),
                                ),
                                SizedBox(height: 10),
                                Text(
                                  stepperLIst[position].value,
                                  style: BaseStyles.textStyle,
                                )
                              ],
                            ),
                          )
                        ]),
                  ),
                );
              }));

并且还使用堆栈

  Widget get stepper2 =>
  Container(
      padding: EdgeInsets.all(15),
      color: Colors.white,
      child: ListView.builder(
          itemCount: stepperLIst.length,
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          itemBuilder: (context, position) {
            return Stack(
              children: <Widget>[
                Positioned(
                  left: 0,
                  top: 0,
                  bottom: 0,
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    verticalDirection: VerticalDirection.down,
                    children: [
                      Image.asset(stepperLIst[position].iconName),
                      SizedBox(height: 10),
                      CustomPaint(painter: LineDashedPainter(lineColor: Colors.grey))

                    ],
                  ), // replace with your image
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 40),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        stepperLIst[position].tittle,
                        style: BaseStyles.textStyle.copyWith(fontFamily: BaseFonts.bold),
                      ),
                      SizedBox(height: 10),
                      Text(
                        stepperLIst[position].value,
                        style: BaseStyles.textStyle,
                      )
                    ],
                  ),
                )
              ],
            );
          }));

使用上面的代码我没有得到准确的输出

任何人都可以帮我创建这种类型的步进器吗

如果需要更多信息,请告诉我。提前致谢。您的努力将受到赞赏。

android ios flutter dart flutter-layout
5个回答
1
投票

我试着接近你的答案。我知道现在回复已经太晚了。但我正在解决我的问题并上网。我找到了你的问题,我得到了解决方案,所以,这就是......

import 'package:flutter/material.dart';

class CustomStepper extends StatelessWidget {
  const CustomStepper({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Container(
              margin: const EdgeInsets.only(left: 8, right: 5),
              height: 18,
              width: 18,
              decoration: BoxDecoration(
                  color: Colors.red,
                  shape: BoxShape.circle,
                  border: Border.all(color: Colors.black)),
            ),
            const Text("Title",style: TextStyle(fontWeight: FontWeight.bold)),
          ],
        ),
        Container(
          margin: const EdgeInsets.only(left: 17),
          padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 5),
          decoration: const BoxDecoration(
              border: Border(
                  left: BorderSide(
            color: Colors.red,
          ))),
          child: const Text('SubTitle\nAbc'),
        ),
      ],
    );
  }
}


1
投票

希望这个包有帮助:another_stepper:^1.0.4

另一个步进器( 步进器列表:步进器数据, stepperDirection: Axis.vertical, 水平步进器高度:70, )


0
投票

我有一些资源可以与您分享。只需检查一下这些内容,看看是否适合您。这些是:

如果您确实想要这些交错线代替步进器中图标之间的单个垂直线,请查看库的代码并通过一些最小的更改制作您自己的小部件。


0
投票

我有主意了~

Stack(
        children: [
          Container(
            margin: const EdgeInsets.only(left: 24, top:2),
            padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 0),
            decoration: shown
                ? const BoxDecoration(
                    border: Border(
                        left: BorderSide(
                    width: 2,
                    color: Color(0xFFDDDDDD),
                  )))
                : null,
            child: Padding(
                padding: const EdgeInsets.only(bottom: 20),
                child: Text(txt,
                    style: const TextStyle(
                      color: Color(0xFF1A1A1A),
                      fontWeight: FontWeight.w400,
                      fontSize: 13.0,
                    ))),
          ),
          const SizedBox(
            height: 0,
            width: 50,
            child: Icon(Icons.circle, color: Color(0xFF222222), size: 16),
          ),
        ],
      )

演示 https://img.alicdn.com/imgextra/i3/O1CN01TMfTZI1MFzdk535xL_!!6000000001406-0-tps-377-254.jpg


0
投票

这是一个迟到的回复,但由于我发现这个问题没有得到解答,这是我的解决方案。它基于 Flutter 版本 3+,但也适用于 Flutter 2+。

方法 1 - 使用
Row
/
Column
小部件

这里我在

rows
中使用 2 个
column
,并在
listview
中重复它们。
VerticalDivider
小部件是一条直线,但您可以使用其他方法(例如
CustomPaint
Container
)来创建虚线或使用flutter_dash

等库

点击这里在DartPad上查看实用的解决方案演示或在此处展示

List<Map<String, dynamic>> userInfoList = [
    {
      'icon': const Icon(Icons.info, color: Colors.orange),
      'title': 'About',
      'content':
          '\$ - American - Restuarant - Western Food\nLocally Resto with the one and only master recipe.\nIn this industry since 1988 - +1182 218 281',
    },
    {
      'icon': const Icon(Icons.web, color: Colors.lightBlueAccent),
      'title': 'Website',
      'content': 'www.moscorestourant.com',
    },
    {
      'icon': const Icon(Icons.location_on, color: Colors.pink),
      'title': 'Location',
      'content': '100 Peachtree Boston 30308',
    },
    {
      'icon': const Icon(Icons.person, color: Colors.greenAccent),
      'title': 'Contact Person',
      'content': 'Jenny F.\[email protected]\n+ 999 999 999',
    },
  ];

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Material(
        child: SingleChildScrollView(
          child: ListView.builder(
            itemCount: userInfoList.length,
            physics: const NeverScrollableScrollPhysics(),
            shrinkWrap: true,
            itemBuilder: (BuildContext content, int index) {
              return Padding(
                padding: const EdgeInsets.only(bottom: 5.0),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Expanded(
                          flex: 1,
                          child: userInfoList[index]['icon'],
                        ),
                        Expanded(
                          flex: 10,
                          child: Text(
                            userInfoList[index]['title'],
                            maxLines: null,
                            style: const TextStyle(
                              color: Colors.black,
                              fontWeight: FontWeight.w700,
                              fontSize: 16.0,
                            ),
                          ),
                        ),
                      ],
                    ),
                    IntrinsicHeight(
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          const Expanded(
                            flex: 1,
                            child: VerticalDivider(
                              color: Colors.black,
                              thickness: 2.0,
                            ),
                          ),
                          Expanded(
                            flex: 10,
                            child: Text(
                              userInfoList[index]['content'],
                              maxLines: null,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              );
            },
          ),
        ),
      ),
    );

方法 2 - 使用
Stepper
小组件

虽然设计与您的设计不完全一样,但它仍然是具有类似结果的可能方法。

  1. 我使用
    stepIconBuilder
    小部件的
    Stepper()
    参数来自定义图标。
  2. 我使用
    controlsBuilder
    小部件的
    Stepper()
    参数来自定义要缩小的“下一步”和“后退”按钮。

点击这里在DartPad上查看实用的解决方案演示或在此处展示

List<Map<String, dynamic>> userInfoList = [
    {
      'icon': const Icon(Icons.info, color: Colors.orange),
      'title': 'About',
      'content':
      '\$ - American - Restuarant - Western Food\nLocally Resto with the one and only master recipe.\nIn this industry since 1988 - +1182 218 281',
    },
    {
      'icon': const Icon(Icons.web, color: Colors.lightBlueAccent),
      'title': 'Website',
      'content': 'www.moscorestourant.com',
    },
    {
      'icon': const Icon(Icons.location_on, color: Colors.pink),
      'title': 'Location',
      'content': '100 Peachtree Boston 30308',
    },
    {
      'icon': const Icon(Icons.person, color: Colors.greenAccent),
      'title': 'Contact Person',
      'content': 'Jenny F.\[email protected]\n+ 999 999 999',
    },
  ];

  @override
  Widget build(BuildContext context) {
    List<Step> stepsList = <Step>[
      Step(
        title: Text(userInfoList[0]['title']),
        subtitle: Text(userInfoList[0]['content']),
        content: Container(),
      ),
      Step(
        title: Text(userInfoList[1]['title']),
        subtitle: Text(userInfoList[1]['content']),
        content: Container(),
      ),
      Step(
        title: Text(userInfoList[2]['title']),
        subtitle: Text(userInfoList[2]['content']),
        content: Container(),
      ),
      Step(
        title: Text(userInfoList[3]['title']),
        subtitle: Text(userInfoList[3]['content']),
        content: Container(),
      ),
    ];

    return SafeArea(
      child: Material(
        child: SingleChildScrollView(
          child: Stepper(
            steps: stepsList,
            connectorColor: MaterialStateProperty.all(
              Colors.black,
            ),
            controlsBuilder: (BuildContext context, _) {
              return const SizedBox.shrink();
            },
            stepIconBuilder: (int step, StepState state) {
              return userInfoList[step]['icon'];
            },
            onStepTapped: (int index) {},
          ),
        ),
      ),
    );

此方法的主要问题之一是图标/步骤的背景颜色与垂直线共享相同的参数 (

connectorColor
)。这意味着使用
Colors.transparent
删除图标背景,您也会丢失垂直线。

© www.soinside.com 2019 - 2024. All rights reserved.