Flutter Rotate CupertinoPicker
Есть ли способ повернуть CupertinoPicker во Flutter на 90 градусов? Чтобы можно было ковырять по горизонтали, а не по вертикали. Transform.rotate не подходит, потому что тогда ширина Picker ограничивается высотой родительского виджета. Или есть какой-нибудь хороший способ заставить средство выбора купертино быть больше, чем его родительский виджет?
2 ответа
Как насчет виджета RotatedBox?
RotatedBox(
quarterTurns: 1,
child: CupertinoPicker(...),
)
В отличие от Transform, который применяет преобразование непосредственно перед рисованием, этот объект применяет свое вращение до макета, что означает, что весь повернутый блок занимает ровно столько места, сколько требуется для повернутого дочернего элемента.
Итак, я нашел 2 решения. Сначала вы можете использовать RotatedBox. Спасибо josxha за эту идею. 2. Решение: Сделайте полный пользовательский сборщик. Так что, если у кого-то есть такая же проблема, вы можете использовать мой собственный сборщик. Код - полный беспорядок, пожалуйста, не судите об Имао.
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),
],
),
);
}),
),
);
}
}