首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否有办法对小部件进行有条件的重新生成?

是否有办法对小部件进行有条件的重新生成?
EN

Stack Overflow用户
提问于 2021-02-06 17:28:59
回答 2查看 475关注 0票数 2

我正在尝试重新创建罗宾汉number_change动画幻灯片

因为每次状态号发生变化,我都想运行动画,所以我认为使用状态提供程序会有帮助。

我目前正在使用Redux。

我使用animatedList来添加和删除数字。

我把每一个数字都列成了1-9个垂直数字的列表,以实现幻灯片的上下滑动,但现在我有点纠结于如何只重建改变过的数字。

即使有distinct: true,它们都连接到同一个商店。

我的小部件容器如下所示

代码语言:javascript
运行
复制
class NumberColViewContainer extends StatelessWidget {
  /// A bool to indicate that you have passed a set of 3 digits and starting a new one
  final bool comma;

  /// The [TextStyle] of the number
  final TextStyle textStyle;
  // The [Duration] the animation will take to slide the number into place
  final Duration duration;
  // The curve that is used during the animation
  final Curve curve;

  NumberColViewContainer(
      {@required this.textStyle,
      @required this.duration,
      this.comma = false,
      @required this.curve});
  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, _ViewModel>(
      builder: (context, vm) {
        return NumberColView(
          animateTo: vm.position,
          textStyle: textStyle,
          duration: duration,
          curve: curve,
          comma: comma
        );
      },
      converter: _ViewModel.fromStore,
      distinct: true,
    );
  }
}

class _ViewModel {
  _ViewModel({
    this.position,
    // this.store
  });

  final int  position;
  // final Store<AppState> store;

  static _ViewModel fromStore(Store<AppState> store) {
    return _ViewModel(
      position: store.state.numberSlideEpicPositionState.position,
      // store: store,
    );
  }
}

我的NumberColView(列表数字)到这个

代码语言:javascript
运行
复制
class NumberColView extends StatefulWidget {
  final int animateTo;
  final bool comma;
  final TextStyle textStyle;
  final Duration duration;
  final Curve curve;

  NumberColView(
      {@required this.animateTo,
      @required this.textStyle,
      @required this.duration,
      this.comma = false,
      @required this.curve})
      : assert(animateTo != null && animateTo >= 0 && animateTo < 10);

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

class _NumberColState extends State<NumberColView>
    with SingleTickerProviderStateMixin {
  ScrollController _scrollController;

  double _elementSize = 0.0;

  @override
  void initState() {
    super.initState();
    _scrollController = new ScrollController();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _elementSize = _scrollController.position.maxScrollExtent / 10;
      setState(() {});

      _scrollController.animateTo(_elementSize * widget.animateTo,
          duration: widget.duration, curve: widget.curve);
    });
  }


@override
  void didUpdateWidget(NumberColView oldWidget) {
    if (oldWidget.animateTo != widget.animateTo) {
      _scrollController.animateTo(
          _elementSize * widget.animateTo,
          duration: widget.duration,
          curve: widget.curve);
    }

    super.didUpdateWidget(oldWidget);
  }
  @override
  Widget build(BuildContext context) {
    // print(widget.animateTo);
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        IgnorePointer(
          child: ConstrainedBox(
            constraints: BoxConstraints(maxHeight: _elementSize),
            child: SingleChildScrollView(
              controller: _scrollController,
              child: Column(
                children: List.generate(10, (position) {
                  return Text(position.toString(), style: widget.textStyle);
                }),
              ),
            ),
          ),
        ),
        widget.comma
            ? Container(
                child: Text(', ',
                    style:
                        TextStyle(fontSize: 16, fontWeight: FontWeight.bold)))
            : Container(),
      ],
    );
  }
}

有些东西告诉我,没有我的方法就能达到效果,但是我找不到,所以如果一个人知道另一种更容易的方法,请分享

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-08 23:48:22

这里是,只需使用setState函数。此函数通知框架此对象的内部状态已更改。

只需使用statefulWidget即可。

使用示例

代码语言:javascript
运行
复制
import 'package:flutter/material.dart';

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

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

class _MyAppState extends State<MyApp> {
  var value = 0;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: Text('Flutter is Awesome'),
          ),
          body: Column(
            children: [
              Text('The new value : $value'),
              OutlinedButton(
                onPressed: () {
                  setState(() { 
                    value++; // do your change here 
                  });
                },
                child: Text('Tap to increase'))
            ],
          )),
    );
  }
}

别忘了做Hot restart来确保它能工作。希望它会有用

票数 1
EN

Stack Overflow用户

发布于 2021-02-09 09:46:20

您也可以使用ValueListenableBuilder,从我的角度来看,这是一个更好的解决方案,因为您可以轻松地将它与其他状态管理框架/体系结构集成。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66079809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档