【问题标题】:Flutter Rotate CupertinoPickerFlutter 旋转 CupertinoPicker
【发布时间】:2020-06-26 15:34:51
【问题描述】:

有什么方法可以将 Flutter 中的 CupertinoPicker 旋转 90 度?这样您就可以水平选择而不是垂直选择。 Transform.rotate 不是一个选项,因为 Picker 的宽度被限制为父窗口小部件的高度。或者有什么好方法可以强制 Cupertino 选择器大于其父小部件?

【问题讨论】:

    标签: flutter dart cupertinopicker


    【解决方案1】:

    RotatedBox 小部件怎么样?

    RotatedBox(
      quarterTurns: 1,
      child: CupertinoPicker(...),
    )
    

    与在绘制之前应用变换的 Transform 不同,此对象在布局之前应用其旋转,这意味着整个旋转的框仅占用旋转子对象所需的空间。

    【讨论】:

      【解决方案2】:

      所以我找到了 2 个解决方案。首先,您可以使用 RotatedBox。感谢 josxha 的这个想法。 2.解决方案:制作一个完整的自定义选择器。所以如果有人有同样的问题,你可以使用我的自定义选择器。代码一团糟,请不要评判lmao。

      class CustomPicker extends StatefulWidget {
        CustomPicker(
            {@required double this.width,
            @required double this.height,
            @required double this.containerWidth,
            @required double this.containerHeight,
            @required double this.gapScaleFactor,
            @required List<Widget> this.childrenW,
            Function(int) this.onSnap});
      
        double width;
        double height;
        double containerWidth;
        double containerHeight;
        double gapScaleFactor;
        List<Widget> childrenW;
        Function(int) onSnap;
      
        _CustomPicker createState() => _CustomPicker(width, height, containerWidth,
            containerHeight, gapScaleFactor, childrenW, onSnap);
      }
      
      class _CustomPicker extends State<CustomPicker>
          with SingleTickerProviderStateMixin {
        AnimationController controller;
        double width;
        double height;
        double containerWidth;
        double containerHeight;
        double gapScaleFactor;
        double currentScrollX = 0;
        double oldAnimScrollX = 0;
        double animDistance = 0;
        int currentSnap = 0;
        List<Widget> childrenW;
        List<Positioned> scrollableContainer = [];
        final Function(int) onSnap;
      
        int currentPos;
        _CustomPicker(
            double this.width,
            double this.height,
            double this.containerWidth,
            double this.containerHeight,
            double this.gapScaleFactor,
            List<Widget> this.childrenW,
            Function(int) this.onSnap) {
          initController();
          init();
        }
      
        void initController() {
          controller = AnimationController(
            vsync: this,
            duration: Duration(milliseconds: 200),
            lowerBound: 0,
            upperBound: 1,
          )..addListener(() {
              setState(() {
                currentScrollX = oldAnimScrollX + controller.value * animDistance;
                init();
              });
            });
        }
      
        void init() {
          scrollableContainer.clear();
          if (currentScrollX < 0) {
            currentScrollX = 0;
          }
          double scrollableLength =
              (containerWidth + containerWidth * gapScaleFactor) *
                      (childrenW.length) -
                  containerWidth * gapScaleFactor;
      
          if (currentScrollX > scrollableLength - containerWidth) {
            currentScrollX = scrollableLength - containerWidth;
          }
          for (int i = 0; i < childrenW.length; i++) {
            double leftPos = width / 2 -
                containerWidth / 2 -
                currentScrollX +
                containerWidth * i +
                containerWidth * gapScaleFactor * i;
            double mid = width / 2 - containerWidth / 2;
            double topPos = containerHeight *
                0.9 *
                ((leftPos - mid).abs() / scrollableLength) /
                2;
            scrollableContainer.add(Positioned(
                //calculate X position
                left: leftPos,
                top: topPos,
                child: Container(
                  height: containerHeight -
                      containerHeight *
                          0.9 *
                          ((leftPos - mid).abs() / scrollableLength),
                  width: containerWidth -
                      containerWidth *
                          0.9 *
                          ((leftPos - mid).abs() / scrollableLength),
                  child: childrenW[i],
                )));
          }
        }
      
        void lookForSnappoint() {
          double distance = 1000000;
          double animVal = 0;
          int index = -2032;
          for (int i = 0; i < scrollableContainer.length; i++) {
            double snappoint = width / 2 - containerWidth / 2;
            double currentLeftPos = width / 2 -
                containerWidth / 2 -
                currentScrollX +
                containerWidth * i +
                containerWidth * gapScaleFactor * i;
            if ((currentLeftPos - snappoint).abs() < distance) {
              distance = (currentLeftPos - snappoint).abs();
              animVal = currentLeftPos - snappoint;
              index = i;
            }
          }
          animDistance = animVal;
          oldAnimScrollX = currentScrollX;
          controller.reset();
          controller.forward();
          this.onSnap(index);
        }
      
        @override
        Widget build(BuildContext context) {
          return Container(
            width: widget.width,
            height: widget.height,
            child: GestureDetector(
              onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
                setState(() {
                  this.currentScrollX -= dragUpdateDetails.delta.dx;
                  init();
                });
              },
              onPanEnd: (DragEndDetails dragEndDetails) {
                lookForSnappoint();
              },
              behavior: HitTestBehavior.translucent,
              child: LayoutBuilder(builder: (context, constraint) {
                return Container(
                  child: Stack(
                    children: <Widget>[
                      Stack(children: scrollableContainer),
                    ],
                  ),
                );
              }),
            ),
          );
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-12-07
        • 1970-01-01
        • 2022-06-23
        • 1970-01-01
        • 1970-01-01
        • 2020-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多