flutter - 如何添加有状态的小部件或如何在底部的另一个屏幕中查看

标签 flutter dart

我创建了一个动画单选圆形按钮,如下图所示:
example
这是下面的代码:

import 'package:flutter/material.dart';
import 'package:catest/utils/animated_radio_btn.dart';

class RadioBtnSim extends StatefulWidget {

  RadioBtnSim({Key key, this.title}) : super(key: key);

  final String title;
  String radioValue = 'First';
  // final bool showFavs;

  // PropertiesGrid(this.showFavs);

  @override
  _RadioBtnSimState createState() => _RadioBtnSimState();
}

class _RadioBtnSimState extends State<RadioBtnSim> with SingleTickerProviderStateMixin {
  _RadioBtnSimState() {
    customBuilder = (BuildContext context, List<dynamic> animValues, Function updateState, String value) {
      return GestureDetector(
        onTap: () {
          setState(() {
            widget.radioValue = value;
          });
        },
        child: Container(
          width: double.infinity,
          height: animValues[0] * 40 + 60,
          color: animValues[1],
          child: Center(
            child: Text(
              value
            )
          ),
        ),
      );
    };
    simpleBuilder = (BuildContext context, List<double> animValues, Function updateState, String value) {
      final alpha = (animValues[0] * 255).toInt();
      return GestureDetector(
        onTap:  () {
          setState(() {
            widget.radioValue = value;
          });
        },
        child: Container(
          padding: EdgeInsets.all(32.0),
          margin: EdgeInsets.symmetric(horizontal: 2.0, vertical: 12.0),
          alignment: Alignment.center,
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: Theme.of(context).primaryColor.withAlpha(alpha),
            border: Border.all(
              color: Theme.of(context).primaryColor.withAlpha(255 - alpha),
              width: 4.0,
            )
          ),
          child: Text(
            value,
            style: Theme.of(context).textTheme.body1.copyWith(fontSize: 20.0),
          )
        )
      );
    };
    dynamicBuilder = (BuildContext context, List<dynamic> animValues, Function updateState, String value) {
      return GestureDetector(
        onTap: () {
          setState(() {
            widget.radioValue = value;
          });
        },
        child: Container(
          alignment: Alignment.center,
          margin: EdgeInsets.symmetric(horizontal: 4.0, vertical: 12.0),
          padding: EdgeInsets.all(32.0 + animValues[0] * 12.0),
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: animValues[1],
            border: Border.all(
              color: animValues[2],
              width: 2.0
            )
          ),
          child: Text(
            value,
            style: Theme.of(context).textTheme.body1.copyWith(
              fontSize: 20.0,
              color: animValues[2]
            ),
          )
        )
      );
    };
  }

  RadioBuilder<String, dynamic> customBuilder;

  RadioBuilder<String, double> simpleBuilder;

  RadioBuilder<String, dynamic> dynamicBuilder;

  AnimationController _controller;

  Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    var animationController = AnimationController(
      duration: Duration(milliseconds: 100),
      vsync: this
    );
    _controller = animationController;
    _animation = CurvedAnimation(
      parent: _controller,
      curve: Curves.ease
    );
    _controller.addListener(() {
      setState(() {});
    });
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              CustomRadio<String, dynamic>(
                value: 'Sim 1',
                groupValue: widget.radioValue,
                animsBuilder: (AnimationController controller) => [
                  CurvedAnimation(
                    parent: controller,
                    curve: Curves.easeInOut
                  ),
                  ColorTween(
                    begin: Colors.white,
                    end: Colors.deepPurple
                  ).animate(controller),
                  ColorTween(
                    begin: Colors.deepPurple,
                    end: Colors.white
                  ).animate(controller),
                ],
                builder: dynamicBuilder,
              ),
              CustomRadio<String, dynamic>(
                value: 'Sim 2',
                groupValue: widget.radioValue,
                animsBuilder: (AnimationController controller) => [
                  CurvedAnimation(
                    parent: controller,
                    curve: Curves.easeInOut
                  ),
                  ColorTween(
                    begin: Colors.white,
                    end: Colors.deepPurple
                  ).animate(controller),
                  ColorTween(
                    begin: Colors.deepPurple,
                    end: Colors.white
                  ).animate(controller),
                ],
                builder: dynamicBuilder,
              ),
            ]
          ),
        ],
      );
  }
}
现在我有另一个屏幕如下:
Screen
这是下面的相关代码:
import 'package:flutter/material.dart';
import 'package:catest/config/app_theme.dart';
import '../widgets/radio_btn_sim.dart';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.only(
              top: 100,
              left: 20,
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  'Sim information',
                  style: TextStyle(fontWeight: FontWeight.bold),
                ),
                Padding(
                  padding: const EdgeInsets.only(
                    left: 30,
                  ),
                  child: DataTable(
                    columns: [
                      DataColumn(label: Text('Sim operator')),
                      DataColumn(
                          label: Row(
                        children: <Widget>[
                          Text('Vodafone'),
                          Image.asset(
                            'assets/images/vodic.png',
                            width: 30,
                            height: 30,
                          )
                        ],
                      )),
                    ],
                    rows: [
                      DataRow(cells: [
                        DataCell(Row(
                          children: <Widget>[
                            Image.asset(
                              'assets/images/sim_ic.png',
                              width: 30,
                              height: 30,
                            ),
                            Text('ICCID'),
                          ],
                        )),
                        DataCell(Text('123456789')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('IMEI')),
                        DataCell(Text('123456789')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('SIM IMSI')),
                        DataCell(Text('123456789')),
                      ]),
                    ],
                  ),
                ),
              ],
            ),
          ),
          //Network provider
          Padding(
            padding: const EdgeInsets.only(
              top: 20,
              left: 20,
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  'Network Provider',
                  style: TextStyle(fontWeight: FontWeight.bold),
                ),
                Padding(
                  padding: const EdgeInsets.only(
                    left: 30,
                  ),
                  child: DataTable(
                    columns: [
                      DataColumn(label: Text('Operator')),
                      DataColumn(
                          label: Row(
                        children: <Widget>[
                          Text('Vodafone NL'),
                          Image.asset(
                            'assets/images/vodic.png',
                            width: 30,
                            height: 30,
                          )
                        ],
                      )),
                    ],
                    rows: [
                      DataRow(cells: [
                        DataCell(Row(
                          children: <Widget>[
                            Text('MCC'),
                          ],
                        )),
                        DataCell(Text('204')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('MNC')),
                        DataCell(Text('04')),
                      ]),
                    ],
                  ),
                ),
              ],
            ),
          ),
          //Serving Cell
          Padding(
            padding: const EdgeInsets.only(
              top: 20,
              left: 20,
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  'Serving Cell',
                  style: TextStyle(fontWeight: FontWeight.bold),
                ),
                Padding(
                  padding: const EdgeInsets.only(
                    left: 30,
                  ),
                  child: DataTable(
                    columns: [
                      DataColumn(label: Text('Data Net')),
                      DataColumn(
                          label: Row(
                        children: <Widget>[
                          Text('LTE'),
                        ],
                      )),
                    ],
                    rows: [
                      DataRow(cells: [
                        DataCell(Row(
                          children: <Widget>[
                            Text('Data type'),
                          ],
                        )),
                        DataCell(Text('LTE')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('TAC')),
                        DataCell(Text('62603')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('PCI')),
                        DataCell(Text('118')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('ECI')),
                        DataCell(Text('12315644(5465-567)')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('EARFCN')),
                        DataCell(Text('1300/19300')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('EARFCN')),
                        DataCell(Text('1300/19300')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('FREQ')),
                        DataCell(Text('1815/1720')),
                      ]),
                      DataRow(cells: [
                        DataCell(Text('BAND')),
                        DataCell(Text('3 FDD')),
                      ]),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
所以现在我想将我创建的单选按钮放在HomeScreen的底部,如下图所示:
screen_home
这是utilsanimation part:
library custom_radio;

import 'package:flutter/material.dart';

typedef AnimationsBuilder<T> = List<Animation<T>> Function(AnimationController);

typedef RadioBuilder<T, U> = Widget Function(BuildContext context, List<U> animValues, Function updateState, T value);
class CustomRadio<T, U> extends StatefulWidget {

  final RadioBuilder<T, U> builder;

  /// The duration of the animation controller
  final Duration duration;

  /// Returns the list of child animations whose values will be passed to the builder.
  /// Called on initState.
  final AnimationsBuilder<U> animsBuilder;
  
  final T value;
  
  final T groupValue;

  bool get checked => value == groupValue;

  CustomRadio({
    Key key,
    this.animsBuilder,
    this.duration = const Duration(milliseconds: 600),
    @required this.builder,
    @required this.value,
    @required this.groupValue,
  })  : assert(duration != null),
        super(key: key);

  @override
  State<CustomRadio> createState() => _CustomRadioState<T, U>();
}

class _CustomRadioState<T, U> extends State<CustomRadio<T, U>>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  List<Animation> _animations;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(duration: widget.duration, vsync: this);
    _animations = widget.animsBuilder(_controller);
    _animations.forEach((anim) => anim.addListener(() => setState(() {})));
    if (widget.checked)
      _controller.value = 1.0;
    else
      _controller.value = 0.0;
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  void _updateState() {
    setState(() {
      if (widget.checked && _controller.status != AnimationStatus.completed) {
        _controller.forward();
      } else {
        _controller.reverse();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    if ((widget.checked &&
            (_controller.status == AnimationStatus.dismissed ||
                _controller.status == AnimationStatus.reverse)) ||
        (!widget.checked &&
            (_controller.status == AnimationStatus.completed ||
                _controller.status == AnimationStatus.forward))) {
      _updateState();
    }

    final anims = _animations.map<U>((anim) => anim.value).toList();
    return widget.builder(
      context,
      anims.length > 0 ? anims : [widget.checked].cast<dynamic>(),
      _updateState,
      widget.value,
    );
  }
}

我希望这会很清楚,如果有任何遗漏的信息,对不起:..

最佳答案

在主屏幕中使用StackPositioned小部件:

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          SingleChildScrollView(
            child: Column(
              children: [
                Padding(
                  padding: const EdgeInsets.only(
                    top: 100,
                    left: 20,
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text(
                        'Sim information',
                        style: TextStyle(fontWeight: FontWeight.bold),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(
                          left: 30,
                        ),
                        child: DataTable(
                          columns: [
                            DataColumn(label: Text('Sim operator')),
                            DataColumn(
                                label: Row(
                              children: <Widget>[
                                Text('Vodafone'),
                                Image.asset(
                                  'assets/images/vodic.png',
                                  width: 30,
                                  height: 30,
                                )
                              ],
                            )),
                          ],
                          rows: [
                            DataRow(cells: [
                              DataCell(Row(
                                children: <Widget>[
                                  Image.asset(
                                    'assets/images/sim_ic.png',
                                    width: 30,
                                    height: 30,
                                  ),
                                  Text('ICCID'),
                                ],
                              )),
                              DataCell(Text('123456789')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('IMEI')),
                              DataCell(Text('123456789')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('SIM IMSI')),
                              DataCell(Text('123456789')),
                            ]),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
                //Network provider
                Padding(
                  padding: const EdgeInsets.only(
                    top: 20,
                    left: 20,
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text(
                        'Network Provider',
                        style: TextStyle(fontWeight: FontWeight.bold),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(
                          left: 30,
                        ),
                        child: DataTable(
                          columns: [
                            DataColumn(label: Text('Operator')),
                            DataColumn(
                                label: Row(
                              children: <Widget>[
                                Text('Vodafone NL'),
                                Image.asset(
                                  'assets/images/vodic.png',
                                  width: 30,
                                  height: 30,
                                )
                              ],
                            )),
                          ],
                          rows: [
                            DataRow(cells: [
                              DataCell(Row(
                                children: <Widget>[
                                  Text('MCC'),
                                ],
                              )),
                              DataCell(Text('204')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('MNC')),
                              DataCell(Text('04')),
                            ]),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
                //Serving Cell
                Padding(
                  padding: const EdgeInsets.only(
                    top: 20,
                    left: 20,
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text(
                        'Serving Cell',
                        style: TextStyle(fontWeight: FontWeight.bold),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(
                          left: 30,
                        ),
                        child: DataTable(
                          columns: [
                            DataColumn(label: Text('Data Net')),
                            DataColumn(
                                label: Row(
                              children: <Widget>[
                                Text('LTE'),
                              ],
                            )),
                          ],
                          rows: [
                            DataRow(cells: [
                              DataCell(Row(
                                children: <Widget>[
                                  Text('Data type'),
                                ],
                              )),
                              DataCell(Text('LTE')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('TAC')),
                              DataCell(Text('62603')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('PCI')),
                              DataCell(Text('118')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('ECI')),
                              DataCell(Text('12315644(5465-567)')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('EARFCN')),
                              DataCell(Text('1300/19300')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('EARFCN')),
                              DataCell(Text('1300/19300')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('FREQ')),
                              DataCell(Text('1815/1720')),
                            ]),
                            DataRow(cells: [
                              DataCell(Text('BAND')),
                              DataCell(Text('3 FDD')),
                            ]),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
          Positioned(
            bottom: 0,
            child: SizedBox(
              width: MediaQuery.of(context).size.width,
              child: RadioBtnSim(
              ),
            ),
          ),
        ],
      ),
    );
  }
}
删除Scaffold中存在的RadioBtnSim
return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        CustomRadio<String, dynamic>(
          value: 'Sim 1',
          groupValue: widget.radioValue,
          animsBuilder: (AnimationController controller) => [
            CurvedAnimation(parent: controller, curve: Curves.easeInOut),
            ColorTween(begin: Colors.white, end: Colors.deepPurple)
                .animate(controller),
            ColorTween(begin: Colors.deepPurple, end: Colors.white)
                .animate(controller),
          ],
          builder: dynamicBuilder,
        ),
        CustomRadio<String, dynamic>(
          value: 'Sim 2',
          groupValue: widget.radioValue,
          animsBuilder: (AnimationController controller) => [
            CurvedAnimation(parent: controller, curve: Curves.easeInOut),
            ColorTween(begin: Colors.white, end: Colors.deepPurple)
                .animate(controller),
            ColorTween(begin: Colors.deepPurple, end: Colors.white)
                .animate(controller),
          ],
          builder: dynamicBuilder,
        ),
      ],
    );
输出:
enter image description here

关于flutter - 如何添加有状态的小部件或如何在底部的另一个屏幕中查看,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63540618/

相关文章:

Flutter - 更改 SVG 图标颜色

flutter - 将list <int>转换为字符串 flutter

flutter - 无法从API提取ID数据。怎么修?

Dart - 双数据类型加法导致长十进制值

dart - 通过比较 Dart 中的索引对列表进行排序

flutter - 如何在flutter中删除缓存和应用程序目录

flutter 布局 : VerticalDividers not shown

android - 如何在 Flutter 中检索没有文本字段的文本输入

dart - 带有可选参数的可选回调

xml - 如何在Flutter中对来自HttpClient流的XML元素进行分组