diff --git "a/Flutter \345\274\200\345\217\221\350\265\204\346\226\231\346\225\264\347\220\206.md" "b/Flutter \345\274\200\345\217\221\350\265\204\346\226\231\346\225\264\347\220\206.md" index 9fd4df8e0cdbc5139d3e29165b5152911b5beea3..976077a9bff9783f564bfbb16efb3f16c859dade 100644 --- "a/Flutter \345\274\200\345\217\221\350\265\204\346\226\231\346\225\264\347\220\206.md" +++ "b/Flutter \345\274\200\345\217\221\350\265\204\346\226\231\346\225\264\347\220\206.md" @@ -97,6 +97,7 @@ 2. [Flutter layout 练习](https://docs.flutter.cn/ui/layout/tutorial) 3. [Flutter Codelabs](https://docs.flutter.cn/codelabs) 4. [Flutter cookbook](https://docs.flutter.cn/cookbook) +5. [Flutter 实战 2](https://book.flutterchina.club/) ### 三、Flutter 社区 diff --git a/flutter_samples/flutter_layout_application/lib/layout/singleListViewBuilderLayout.dart b/flutter_samples/flutter_layout_application/lib/layout/singleListViewBuilderLayout.dart new file mode 100644 index 0000000000000000000000000000000000000000..ff273a4fc337aec573570a87c1c0cc047b9f5f83 --- /dev/null +++ b/flutter_samples/flutter_layout_application/lib/layout/singleListViewBuilderLayout.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_layout_application/model/todo.dart'; + +import '../main.dart'; + +class SingleListViewBuilderLayout extends StatefulWidget { + final CardItem cardItem; // 新增参数 + + const SingleListViewBuilderLayout({super.key, required this.cardItem}); + + @override + _SingleListViewBuilderLayoutState createState() => + _SingleListViewBuilderLayoutState(); +} + +class _SingleListViewBuilderLayoutState + extends State { + List items = [ + ToDo(id: '1', title: '吃早饭'), + ToDo(id: '2', title: '代码 bug Fix'), + ToDo(id: '3', title: '下班做饭'), + ]; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Text("基本列表 ListBuilder"), + Expanded( + child: ListView.builder( + itemCount: items.length, + itemBuilder: (context, idx) { + var item = items[idx]; + return Padding( + padding: const EdgeInsets.all(8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Checkbox( + value: item.isDone, + onChanged: (value) { + setState(() { + item.isDone = value ?? false; + }); + }, + ), + Text(item.title), + Text(item.isDone ? '已完成' : '未完成'), + ], + ), + ); + }, + ), + ), + ], + ), + ); + } +} diff --git a/flutter_samples/flutter_layout_application/lib/layout/singleListViewLayout.dart b/flutter_samples/flutter_layout_application/lib/layout/singleListViewLayout.dart new file mode 100644 index 0000000000000000000000000000000000000000..da0f135222fbe38c12539456deb245be43474e0a --- /dev/null +++ b/flutter_samples/flutter_layout_application/lib/layout/singleListViewLayout.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +import '../main.dart'; + +class SingleListViewLayout extends StatelessWidget { + final CardItem cardItem; // 新增参数 + + const SingleListViewLayout({super.key, required this.cardItem}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Text("基本列表 ListTitle"), + Column( + spacing: 20, + children: [ + ListTile(leading: Icon(Icons.map), title: Text('Map')), + ListTile(leading: Icon(Icons.photo_album), title: Text('Album')), + ListTile(leading: Icon(Icons.phone), title: Text('Phone')), + ], + ), + ], + ), + ); + } +} diff --git a/flutter_samples/flutter_layout_application/lib/layout/singleListViewRowLayout.dart b/flutter_samples/flutter_layout_application/lib/layout/singleListViewRowLayout.dart new file mode 100644 index 0000000000000000000000000000000000000000..50ff8eeb0262b37d889e75d62ff7c2c3cc829df7 --- /dev/null +++ b/flutter_samples/flutter_layout_application/lib/layout/singleListViewRowLayout.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +import '../main.dart'; + +class SingleListViewRowLayout extends StatelessWidget { + final CardItem cardItem; // 新增参数 + + const SingleListViewRowLayout({super.key, required this.cardItem}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Center( + child: ListView( + // This next line does the trick. + scrollDirection: Axis.horizontal, + children: [borderedImage(), borderedImage()], + ), + ), + ); + } + + Widget borderedImage() { + return SizedBox( + width: 200, + height: 200, + child: Card(child: Image.asset('images/lake.jpg', fit: BoxFit.cover)), + ); + } +} diff --git a/flutter_samples/flutter_layout_application/lib/main.dart b/flutter_samples/flutter_layout_application/lib/main.dart index 38c1c2b465aa357e65b073f8d9bc1a697296f853..8fd02e3a78d41689fd51d13958a91aacc57652ab 100644 --- a/flutter_samples/flutter_layout_application/lib/main.dart +++ b/flutter_samples/flutter_layout_application/lib/main.dart @@ -45,6 +45,21 @@ class _MyHomePageState extends State { content: '简单纵向布局', key: 'column_layout', ), + CardItem( + title: 'listtitle_layout', + content: '简单列表布局', + key: 'listtitle_layout', + ), + CardItem( + title: 'listview_row_layout', + content: '简单横向列表布局', + key: 'listview_row_layout', + ), + CardItem( + title: 'listview_builder_layout', + content: 'listview builder 布局', + key: 'listview_builder_layout', + ), ]; void _onCategorySelected(String category) { @@ -65,6 +80,21 @@ class _MyHomePageState extends State { content: '简单纵向布局', key: 'column_layout', ), + CardItem( + title: 'listview_layout', + content: '简单列表布局', + key: 'listview_layout', + ), + CardItem( + title: 'listview_row_layout', + content: '简单横向列表布局', + key: 'listview_row_layout', + ), + CardItem( + title: 'listview_builder_layout', + content: 'listview builder 布局', + key: 'listview_builder_layout', + ), ]; break; case '设置': diff --git a/flutter_samples/flutter_layout_application/lib/model/todo.dart b/flutter_samples/flutter_layout_application/lib/model/todo.dart new file mode 100644 index 0000000000000000000000000000000000000000..6c98a5a28cc7596b4078818962acf31850d9a522 --- /dev/null +++ b/flutter_samples/flutter_layout_application/lib/model/todo.dart @@ -0,0 +1,7 @@ +class ToDo { + final String id; + final String title; + bool isDone; + + ToDo({required this.id, required this.title, this.isDone = false}); +} diff --git a/flutter_samples/flutter_layout_application/lib/preview_page.dart b/flutter_samples/flutter_layout_application/lib/preview_page.dart index 9f3cd7693cdc5c2ccc85d60bc432afc7f61273a8..0cbaed5fcd612f11bbb1508074fde267e1640870 100644 --- a/flutter_samples/flutter_layout_application/lib/preview_page.dart +++ b/flutter_samples/flutter_layout_application/lib/preview_page.dart @@ -2,6 +2,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_layout_application/layout/project/columnLayoutProject.dart'; import 'package:flutter_layout_application/layout/singleColumnLayout.dart'; import 'package:flutter_layout_application/layout/singleLayout.dart'; +import 'package:flutter_layout_application/layout/singleListViewBuilderLayout.dart'; +import 'package:flutter_layout_application/layout/singleListViewLayout.dart'; +import 'package:flutter_layout_application/layout/singleListViewRowLayout.dart'; import 'package:flutter_layout_application/layout/singleRowLayout.dart'; import 'main.dart'; // 引入 CardItem 类 @@ -30,6 +33,12 @@ class PreviewPage extends StatelessWidget { return SingleRowLayout(cardItem: cardItem); } else if (cardItem.key == 'column_layout') { return SingleColumnLayout(cardItem: cardItem); + } else if (cardItem.key == 'listtitle_layout') { + return SingleListViewLayout(cardItem: cardItem); + } else if (cardItem.key == 'listview_row_layout') { + return SingleListViewRowLayout(cardItem: cardItem); + } else if (cardItem.key == 'listview_builder_layout') { + return SingleListViewBuilderLayout(cardItem: cardItem); } else { return Text(cardItem.content); // 根据需求调整逻辑 }