滚动列表与动态加载
ListView
ListView(
children: [
Container(
height: 300,
width: 300,
color: Colors.red,
),
Text('nihao flutter'),
Text('Hello world'),
Container(
height: 300,
width: 300,
color: Colors.red,
),
Text('Hello world'),
Container(
height: 300,
width: 300,
color: Colors.red,
),
Text('Hello world'),
Container(
height: 300,
width: 300,
color: Colors.red,
),
Text('Hello world'),
Container(
height: 300,
width: 300,
color: Colors.red,
),
],
),
ListView.builder

ListView.builder(
itemCount: 100,
itemExtent: 100,
cacheExtent: 300,
itemBuilder: (context, index) {
return Container(
height: 100,
width: double.infinity,
color: Colors.blue[200],
alignment: Alignment.center,
child: Text('$index'));
},
),
ListView.separated
ListView.separated(
separatorBuilder: (context, index) {
return Divider(
height: 1,
);
},
itemCount: 100,
cacheExtent: 300,
itemBuilder: (context, index) {
return Container(
height: 100,
width: double.infinity,
color: Colors.blue[200],
alignment: Alignment.center,
child: Text('$index'));
},
)
深入详解ListView组件
Scrollbar(
child: ListView.builder(
controller: _controller,
padding: const EdgeInsets.only(bottom: 140),
itemExtent: 60,
itemCount: 80,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.person),
title: Text('Name'),
subtitle: Text('Introduction'),
trailing: IconButton(
icon: Icon(Icons.delete_outline),
),
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_controller.animateTo(_controller.offset + 200,
duration: Duration(seconds: 2),
curve: Curves.linear);
},
child: Icon(Icons.arrow_circle_down_outlined),
),
),
点击标题回到top
AppBar(
centerTitle: true,
title: GestureDetector(
onTap: () {
_controller.animateTo(
-20.0,
duration: Duration(seconds: 1),
curve: Curves.linear);
},
child: Text(
'滚动列表',
)),
),
下拉刷新与通知事件
RefreshIndicator(
strokeWidth: 2.0,
color: Colors.white,
backgroundColor: Colors.black,
onRefresh: () async {
await Future.delayed(Duration(seconds: 2));
},
child: Scrollbar(
child: ListView.builder(
controller: _controller,
padding: const EdgeInsets.only(bottom: 140),
itemExtent: 60,
itemCount: 80,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.person),
title: Text('Name'),
subtitle: Text('Introduction'),
trailing: IconButton(
icon: Icon(Icons.delete_outline),
),
);
},
),
),
),
NotificationListener(
onNotification: (ScrollNotification _event) {
print(_event);
return false;
},
child: ListView.builder(
controller: _controller,
padding: const EdgeInsets.only(bottom: 140),
itemExtent: 60,
itemCount: 80,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.person),
title: Text('Name'),
subtitle: Text('Introduction'),
trailing: IconButton(
icon: Icon(Icons.delete_outline),
),
);
},
),
),
支持滑动删除的Dismissible
Dismissible(
confirmDismiss: (direction) async {
await Future.delayed(Duration(seconds: 2));
return true;
},
onResize: () {
print('on resizing');
},
dismissThresholds: {
DismissDirection.startToEnd: 0.4,
DismissDirection.endToStart: 0.4
},
resizeDuration: Duration(seconds: 5),
movementDuration: Duration(seconds: 5),
background: Container(color: Colors.red),
secondaryBackground: Container(color: Colors.black),
onDismissed: (direction) {
print(direction);
},
key: UniqueKey(),
child: Container(
height: 50,
color: Colors.blue[index % 9 * 100],
),
);
实例:GitHub最新动态
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _events = [];
_refresh() async {
final res = await http.get("https://api.github.com/events");
if (res.statusCode == 200) {
final List json = convert.jsonDecode(res.body);
setState(() {
_events.clear();
_events.addAll(json.map((element) => GitEvent(element)));
});
}
}
@override
Widget build(BuildContext context) {
return Scrollbar(
child: RefreshIndicator(
onRefresh: () async {
await _refresh();
},
child: ListView(
children: _events.map<Widget>((event) {
return Dismissible(
confirmDismiss: (_) async {
return showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('Are you sure?'),
content: Text('Do you want to delete this item?'),
actions: [
FlatButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text('Cancel')),
FlatButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text('Delete'))
],
);
},
);
},
onDismissed: (_) {
setState(() {
_events.removeWhere((e) => e.id == event.id);
});
},
key: ValueKey(event.id),
child: ListTile(
leading: Image.network(
'http://www.tobutomi.top/NewsCat/images/avatar/avatar.jpg'),
title: Text('${event.userName}'),
subtitle: Text('${event.repoName}'),
),
);
}).toList(),
),
),
);
}
}
class GitEvent {
String id;
String userName;
String avatarUrl;
String repoName;
GitEvent(json) {
this.id = json['id'];
this.userName = json['actor']['login'];
this.avatarUrl = json['actor']['avatar_url'];
this.repoName = json['repo']['name'];
}
@override
String toString() {
return 'GitEvent{id:$id,userName:$userName,avatarUrl:$avatarUrl,repoName:$repoName}';
}
}
GridView(二维网格列表)详解
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
childAspectRatio: 16 / 9,
mainAxisSpacing: 2.0,
crossAxisSpacing: 4.0,
),
itemCount: 80,
itemBuilder: (context, index) {
return Center(
child: Container(
width: double.infinity,
height: 100,
color: Colors.blue[index % 8 * 100],
child: Text('$index'),
),
);
});
ListWheelScrollView(
physics: FixedExtentScrollPhysics(),
onSelectedItemChanged: (index) => print("selected $index"),
magnification: 2.5,
useMagnifier: true,
diameterRatio: 2.0,
itemExtent: 100,
children: List.generate(
20,
(index) => Container(
color: Colors.blue,
child: Text('Hello'),
alignment: Alignment.center,
)),
);
拓展,横向
RotatedBox(
quarterTurns: 1,
child: ListWheelScrollView(
physics: FixedExtentScrollPhysics(),
onSelectedItemChanged: (index) => print("selected $index"),
magnification: 2.5,
useMagnifier: true,
diameterRatio: 2.0,
itemExtent: 100,
children: List.generate(
20,
(index) => RotatedBox(
quarterTurns: -1,
child: Container(
child: Text(
'$index',
style: TextStyle(fontSize: 48),
),
alignment: Alignment.center,
),
)),
),
);
PageView
PageView(
pageSnapping: true,
scrollDirection: Axis.vertical,
children: [
Container(color: Colors.blue),
Container(color: Colors.orange)
],
onPageChanged: (value) => print('selected:$value'),
);
ReorderableListView
ReorderableListView(
children: List.generate(
20, (index) => Text('index is $index', key: UniqueKey())),
onReorder: (int oldIndex, int newIndex) =>
print('moved from $oldIndex to $newIndex'));
SingleChildScrollView(
child: Column(
children: [
FlutterLogo(size: 300),
FlutterLogo(size: 400),
],
),
);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】