我试图有一个水平ListView小部件,放大中心项目。我试着用普通的ListView,但是我不能放大中心的项目。然后在搜索flutter文档时,我遇到了ListWheelScrollView,但不幸的是,它似乎不支持水平子布局。所以基本上我希望创建一个水平ListView与中心项目放大。如果有人能给我指个方向我会很感激的。谢谢
ListView
ListWheelScrollView
zsohkypk1#
编辑:我已经发布了基于此的软件包。pub.dev/packages/list_wheel_scroll_view_x这是我的变通办法。
import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; class ListWheelScrollViewX extends StatelessWidget { final Widget Function(BuildContext, int) builder; final Axis scrollDirection; final FixedExtentScrollController controller; final double itemExtent; final double diameterRatio; final void Function(int) onSelectedItemChanged; const ListWheelScrollViewX({ Key key, @required this.builder, @required this.itemExtent, this.controller, this.onSelectedItemChanged, this.scrollDirection = Axis.vertical, this.diameterRatio = 100000, }) : super(key: key); @override Widget build(BuildContext context) { return RotatedBox( quarterTurns: scrollDirection == Axis.horizontal ? 3 : 0, child: ListWheelScrollView.useDelegate( onSelectedItemChanged: onSelectedItemChanged, controller: controller, itemExtent: itemExtent, diameterRatio: diameterRatio, physics: FixedExtentScrollPhysics(), childDelegate: ListWheelChildBuilderDelegate( builder: (context, index) { return RotatedBox( quarterTurns: scrollDirection == Axis.horizontal ? 1 : 0, child: builder(context, index), ); }, ), ), ); } }
wtlkbnrh2#
您可以通过将内置的ListWheelScrollView与RotatedBox配对来实现这一点。这是一种有效的黑客。
RotatedBox
RotatedBox( quarterTurns: -1, child: ListWheelScrollView( controller: _scrollController, itemExtent: itemWidth, onSelectedItemChanged: (newIndex) { setState(() { selectedIndex = newIndex; }); }, children: List.generate( itemCount, (index) => RotatedBox( quarterTurns: 1, child: AnimatedContainer( duration: Duration(milliseconds: 400), width: index == selectedIndex ? 60 : 50, height: index == selectedIndex ? 60 : 50, alignment: Alignment.center, decoration: BoxDecoration( color: index == selectedIndex ? Colors.red : Colors.grey, shape: BoxShape.circle, ), child: Text('$index'), ), ), ), ), );
Full source Code here我建议在this issue解决之前使用此方法
ddarikpa3#
复制此代码并使用它
import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; class ListWheelScrollViewX extends StatelessWidget { final Axis scrollDirection; final List<Widget>? children; final ScrollController? controller; final ScrollPhysics? physics; final double diameterRatio; final double perspective; final double offAxisFraction; final bool useMagnifier; final double magnification; final double overAndUnderCenterOpacity; final double itemExtent; final double squeeze; final ValueChanged<int>? onSelectedItemChanged; final bool renderChildrenOutsideViewport; final ListWheelChildDelegate? childDelegate; final Clip clipBehavior; const ListWheelScrollViewX({ Key? key, this.scrollDirection = Axis.vertical, this.controller, this.physics, this.diameterRatio = RenderListWheelViewport.defaultDiameterRatio, this.perspective = RenderListWheelViewport.defaultPerspective, this.offAxisFraction = 0.0, this.useMagnifier = false, this.magnification = 1.0, this.overAndUnderCenterOpacity = 1.0, required this.itemExtent, this.squeeze = 1.0, this.onSelectedItemChanged, this.renderChildrenOutsideViewport = false, this.clipBehavior = Clip.hardEdge, required this.children, }) : childDelegate = null, super(key: key); const ListWheelScrollViewX.useDelegate({ Key? key, this.scrollDirection = Axis.vertical, this.controller, this.physics, this.diameterRatio = RenderListWheelViewport.defaultDiameterRatio, this.perspective = RenderListWheelViewport.defaultPerspective, this.offAxisFraction = 0.0, this.useMagnifier = false, this.magnification = 1.0, this.overAndUnderCenterOpacity = 1.0, required this.itemExtent, this.squeeze = 1.0, this.onSelectedItemChanged, this.renderChildrenOutsideViewport = false, this.clipBehavior = Clip.hardEdge, required this.childDelegate, }) : children = null, super(key: key); @override Widget build(BuildContext context) { final _childDelegate = children != null ? ListWheelChildListDelegate( children: children!.map((child) { return RotatedBox( quarterTurns: scrollDirection == Axis.horizontal ? 1 : 0, child: child, ); }).toList()) : ListWheelChildBuilderDelegate( builder: (context, index) { return RotatedBox( quarterTurns: scrollDirection == Axis.horizontal ? 1 : 0, child: childDelegate!.build(context, index), ); }, ); return RotatedBox( quarterTurns: scrollDirection == Axis.horizontal ? 3 : 0, child: ListWheelScrollView.useDelegate( controller: controller, physics: FixedExtentScrollPhysics(), diameterRatio: diameterRatio, perspective: perspective, offAxisFraction: offAxisFraction, useMagnifier: useMagnifier, magnification: magnification, overAndUnderCenterOpacity: overAndUnderCenterOpacity, itemExtent: itemExtent, squeeze: squeeze, onSelectedItemChanged: onSelectedItemChanged, renderChildrenOutsideViewport: renderChildrenOutsideViewport, clipBehavior: clipBehavior, childDelegate: _childDelegate, ), ); } }
示例
ListWheelScrollViewX( scrollDirection: Axis.horizontal, itemExtent: 120, children:... ),
参考list_wheel_scroll_view_x更改:转换为空安全
3b6akqbq4#
你可以使用这个flutter包https://pub.dev/packages/carousel_slider。它也有一个非常有帮助的描述和几个样本,看看它看起来如何。它也与dart 2.0兼容。
o2g1uqev5#
您可以在ListView和PageView沿着NotificationListener的帮助下完成此工作。下面是我的代码相同-
PageView
NotificationListener
import 'dart:math'; import 'package:flutter/material.dart'; const SCALE_FRACTION = 0.9; const FULL_SCALE = 1.0; final PAGER_HEIGHT = SizeConfig.screenHeight*0.32; const PAGER_WIDTH = double.infinity; class PaymentWidget extends StatefulWidget { @override State<StatefulWidget> createState() => _PaymentState(); } class _PaymentState extends State<PaymentWidget> { double viewPortFraction = 0.9; int currentPage = 1; double page = 2.0; PageController pageController; final List<String> _cardsImages = ['image/path1', 'image/path2', 'image/path3', 'image/path4']; @override void initState() { pageController = PageController( initialPage: currentPage, viewportFraction: viewPortFraction); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: null, body: _creditCardsList() ); } Widget _creditCardsList() { return ListView( shrinkWrap: true, children: <Widget>[ Container( height: PAGER_HEIGHT, child: NotificationListener<ScrollNotification>( onNotification: (ScrollNotification notification) { if (notification is ScrollUpdateNotification) { setState(() { page = pageController.page; }); } }, child: PageView.builder( onPageChanged: (pos) { setState(() { currentPage = pos; }); }, physics: BouncingScrollPhysics(), controller: pageController, itemCount: _cardsImages.length, itemBuilder: (context, index) { final scale = max(SCALE_FRACTION, (FULL_SCALE - (index - page).abs()) + viewPortFraction); return CreditCardTile( _cardsImages[index], scale); }, ), ), ), ], ); } Widget CreditCardTile(String image, double scale) { return Align( alignment: Alignment.bottomCenter, child:Container( height: PAGER_HEIGHT * scale, width: PAGER_WIDTH * scale, child: Card( elevation: 5, shadowColor: constColors.blueWhiteShade, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0) ), clipBehavior: Clip.antiAlias, child: Image.asset( image, fit: BoxFit.cover, ), ) ) , ); }
wmvff8tz6#
Transform.rotate( angle: -math.pi / 2, child: ListWheelScrollView() }
使用Transform.rotate
dly7yett7#
添加2个RotatedBox,如下所示
StreamBuilder<DocumentSnapshot>( stream: FirebaseFirestore.instance .collection('Categories') .doc('EcomCat') .snapshots(), builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) { if (snapshot.data == null) { return Center( child: CircularProgressIndicator(), ); } final DocumentSnapshot document = snapshot.data!; final Map<String, dynamic> documentData = document.data() as Map<String, dynamic>; final List Category = documentData['category']; return RotatedBox(quarterTurns: 1, child: ListWheelScrollView.useDelegate(magnification: 200, itemExtent: 180, childDelegate: ListWheelChildBuilderDelegate( childCount: Category.length, builder: (context,index){ return Row( children: [ RotatedBox(quarterTurns: -1, child: ElevatedButton( style: ElevatedButton.styleFrom( padding: EdgeInsets.all(10), shadowColor: Colors.black, primary: Colors.teal, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18))), onPressed: () { setState(() { categoryVal = Category[index].toString(); }); }, child: Text( Category[index].toString(), style: themeData.textTheme.headline4, ), ), ), ], ); }, )), ); }, ),
7条答案
按热度按时间zsohkypk1#
编辑:我已经发布了基于此的软件包。
pub.dev/packages/list_wheel_scroll_view_x
这是我的变通办法。
wtlkbnrh2#
您可以通过将内置的ListWheelScrollView与
RotatedBox
配对来实现这一点。这是一种有效的黑客。Full source Code here
我建议在this issue解决之前使用此方法
输出如下
ddarikpa3#
复制此代码并使用它
示例
参考list_wheel_scroll_view_x
更改:转换为空安全
3b6akqbq4#
你可以使用这个flutter包https://pub.dev/packages/carousel_slider。它也有一个非常有帮助的描述和几个样本,看看它看起来如何。它也与dart 2.0兼容。
o2g1uqev5#
您可以在
ListView
和PageView
沿着NotificationListener
的帮助下完成此工作。下面是我的代码相同-wmvff8tz6#
使用Transform.rotate
dly7yett7#
添加2个RotatedBox,如下所示