首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >颤振旋转CupertinoPicker

颤振旋转CupertinoPicker
EN

Stack Overflow用户
提问于 2020-06-26 15:34:51
回答 2查看 1K关注 0票数 2

有没有办法使CupertinoPicker以90度的速度旋转?这样你就可以水平地而不是垂直地选择。Transform.rotate不是一个选项,因为选择器的宽度仅限于父部件的高度。或者有什么好的方法来迫使库比提诺选择器比它的父部件更大?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-26 17:40:06

RotatedBox小部件怎么样?

代码语言:javascript
复制
RotatedBox(
  quarterTurns: 1,
  child: CupertinoPicker(...),
)

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

票数 2
EN

Stack Overflow用户

发布于 2020-06-26 22:40:45

所以我找到了两个解决方案。首先,您可以使用RotatedBox。为了这个主意,我会去找他的。2.解决方案:制作一个完整的自定义选择器。所以如果有人有同样的问题,你可以使用我的自定义选择器。代码完全乱七八糟,请不要评判伊毛。

代码语言:javascript
复制
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),
              ],
            ),
          );
        }),
      ),
    );
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62598099

复制
相关文章

相似问题

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