ovi*_*i_b 7 android slider carousel dart flutter
滑块的每一页都是一个 Card 小部件,其子级为 ListView。
如果卡片不在轮播小部件内,它会随着列表视图内元素的增加而扩展。
我想为滑块的每个页面保持这种行为,但是当我将卡片放入滑块内时,它们不再根据内容调整大小,但似乎有一个预定义的高度(即使我没有指定)任何!)。
如何动态更新滑块内卡片的高度?
这是我的代码:
main.dart文件
import 'package:flutter/material.dart';
import 'carousel.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Slider App',
home: MyHomePage(),
);
}
}
class GeneralEvent {
final String title;
final String desc;
GeneralEvent(this.title, this.desc);
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
final List<GeneralEvent> userEvents = [
GeneralEvent(
"List Item 1",
"Lorem ipsum dolor sit amet, consectetur adipisci elit.",
),
GeneralEvent(
"List Item 2",
"Lorem ipsum dolor sit amet, consectetur adipisci elit.",
),
GeneralEvent(
"List Item 3",
"Lorem ipsum dolor sit amet, consectetur adipisci elit.",
),
GeneralEvent(
"List Item 4",
"Lorem ipsum dolor sit amet, consectetur adipisci elit.",
),
GeneralEvent(
"List Item 5",
"Lorem ipsum dolor sit amet, consectetur adipisci elit.",
),
];
class _MyHomePageState extends State<MyHomePage> {
final List<Card> cards = [
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
'Card 1',
style: TextStyle(fontSize: 24),
),
),
Container(
height: 1,
width: double.infinity,
color: Color.fromRGBO(0, 0, 0, 0.12),
),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (ctx, index) {
return ListTile(
title: Text(
userEvents.sublist(0, 3)[index].title,
),
subtitle: Text(userEvents.sublist(0, 3)[index].desc),
);
},
itemCount: userEvents.sublist(0, 3).length,
),
],
),
),
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
'Card 2',
style: TextStyle(fontSize: 24),
),
),
Container(
height: 1,
width: double.infinity,
color: Color.fromRGBO(0, 0, 0, 0.12),
),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (ctx, index) {
return ListTile(
title: Text(
userEvents.sublist(3)[index].title,
),
subtitle: Text(userEvents.sublist(3)[index].desc),
);
},
itemCount: userEvents.sublist(3).length,
),
],
),
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromRGBO(235, 235, 235, 1),
appBar: AppBar(title: Text('iWantASliderAPP')),
body: Padding(
padding: EdgeInsets.fromLTRB(5, 0, 5, 0),
child: LayoutBuilder(
builder: (context, constraints) {
return ListView(
children: <Widget>[
CarouselWithIndicator(cards),
Padding(
padding: const EdgeInsets.fromLTRB(0, 50, 0, 0),
child: Text(
"if the Card is not in the slider it resize properly:",
),
),
cards[0]
],
);
},
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
和carousel.dart
import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';
class CarouselWithIndicator extends StatefulWidget {
final List cards;
CarouselWithIndicator(this.cards);
@override
_CarouselWithIndicatorState createState() => _CarouselWithIndicatorState();
}
class _CarouselWithIndicatorState extends State<CarouselWithIndicator> {
List<T> map<T>(List list, Function handler) {
List<T> result = [];
for (var i = 0; i < list.length; i++) {
result.add(handler(i, list[i]));
}
return result;
}
int _current = 0;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
CarouselSlider(
// height: // NO HEIGHT SPECIFIED!
viewportFraction: 1.0,
enlargeCenterPage: true,
enableInfiniteScroll: false,
onPageChanged: (index) {
setState(() {
_current = index;
});
},
items: widget.cards.map((card) {
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
child: card,
);
},
);
}).toList(),
),
SizedBox(
height: 5,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: map<Widget>(widget.cards, (index, card) {
return Container(
width: 10.0,
height: 10.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 3.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index ? Colors.grey : Color.fromRGBO(200, 200, 200, 1),
),
);
}),
),
],
);
}
}
Run Code Online (Sandbox Code Playgroud)
我终于在运行时高度确定的帮助下找到了解决方案。链接到运行时大小确定问题:How to get height of a Widget?
只需定义一个高度变量并在测量尺寸的 onChanged 函数中更新它即可。
MeasureSizeRenderObject.dart
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
typedef void OnWidgetSizeChange(Size size);
class MeasureSizeRenderObject extends RenderProxyBox {
Size oldSize;
final OnWidgetSizeChange onChange;
MeasureSizeRenderObject(this.onChange);
@override
void performLayout() {
super.performLayout();
Size newSize = child.size;
if (oldSize == newSize) return;
oldSize = newSize;
WidgetsBinding.instance.addPostFrameCallback((_) {
onChange(newSize);
});
}
}
class MeasureSize extends SingleChildRenderObjectWidget {
final OnWidgetSizeChange onChange;
const MeasureSize({
Key key,
@required this.onChange,
@required Widget child,
}) : super(key: key, child: child);
@override
RenderObject createRenderObject(BuildContext context) {
return MeasureSizeRenderObject(onChange);
}
}
Run Code Online (Sandbox Code Playgroud)
导入上面的 dart 文件就可以了。
就我而言,我有一个日期列表和一个每天运行时间的 Map<String,List> 。因此,当添加新的运行时间时,ListView 的长度就会增加。
List _days = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'];
地图<字符串,列表> _operationalHours = {};
我正在从 Firebase Cloud Firestore 填充运行时间。
轮播滑块代码:
CarouselSlider.builder(
itemCount: days.length,
itemBuilder: (BuildContext context, int index, int realIdx) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Color(0xff3b3b3b),
child: Container(
width: displayWidth(context),
padding: EdgeInsets.all(15.0),
child: Column(
children: [
Text(
days[index],
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20),
),
SizedBox(
height: 15,
),
Column(
children: [
MeasureSize(
onChange: (size) {
height = size.height;
print("log" + height.toString());
setState(() {});
},
child: ListView.builder(
shrinkWrap: true,
itemCount: operationalHours[days[index]]
.length,
itemBuilder: (context, i) {
return getTimeSlot(
operationalHours[days[index]][i]);
}),
)
],
)
],
),
),
);
},
options: new CarouselOptions(
autoPlay: false,
viewportFraction: 1.0,
height: 100 + height,
enlargeCenterPage: false,
enableInfiniteScroll: false,
onPageChanged: (index, reason) {
setState(() {
_current = index;
});
}),
),
Run Code Online (Sandbox Code Playgroud)
如果我在将代码从 IDE 复制到 StackOverflow 时犯了任何拼写错误或错误,请告诉我。我会更新答案。
小智 5
我认识到使用 CarouselSlider 来处理不同的内容大小是很困难的。
我改用这个包: https: //pub.dev/packages/expandable_page_view
int current = 0;
Container(
width: MediaQuery.of(context).size.width,
child: ExpandablePageView.builder(
onPageChanged: (index) {
setState(() {
current = index;
});
},
itemCount: itemList.length,
itemBuilder: (context, index) {
return GalleryItemThumbnail(
galleryItemModel: GalleryItemModel(id: itemList[index]),
onTap: () {
_open(context, index);
},
);
},
),
),
Run Code Online (Sandbox Code Playgroud)
小智 2
这是图书馆中的一个已知问题。这是lib创建者的答案Currently there is no way to define a dynamic height for each carousel item. But I think it can be done by creating a dynamic height container in the carousel item.
对于整个对话,请查看问题:https://github.com/serenader2014/flutter_carousel_slider/issues/106
| 归档时间: |
|
| 查看次数: |
16243 次 |
| 最近记录: |