将 ListView 转换为 ListView.builder
Posted
技术标签:
【中文标题】将 ListView 转换为 ListView.builder【英文标题】:convert ListView to ListView.builder 【发布时间】:2021-03-27 10:08:12 【问题描述】:我正在尝试在下面的代码中呈现 LayoutBuilder。这需要在 LayoutBuilder 中 以及将 GridView 转换为 GridView.builder。在 item.builder 中似乎无法使用地图功能。转换的总体方法是什么?
https://dartpad.dev/46d5b4ad7524b792ea9995bcc158eb0e
【问题讨论】:
【参考方案1】:您的 LayoutBuilder 看起来像:
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints)
return (isListViewOn && !isGridViewOn)
? ListView.builder(
itemCount: hotels.length,
itemBuilder: (context, index)
return ListTile(
leading: Text(hotels[index].uuid),
title: Text(hotels[index].name),
subtitle: Text(hotels[index].poster),
);
,
)
: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: hotels.length,
itemBuilder: (cpntext, index)
return GridTile(
header: Text(hotels[index].poster),
child: Text(hotels[index].uuid),
footer: Text(hotels[index].name),
);
,
);
,
)
整个代码看起来像这样。注意:我已经在您的代码中对从 URL 接收到的数据进行了硬编码,并重新创建了 HotelPreview 类:
import 'package:flutter/material.dart';
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
initialRoute: '/',
routes:
'/': (BuildContext context) => const MyHomePage(),
,
);
class MyHomePage extends StatefulWidget
const MyHomePage(Key key, this.title) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
bool isLoading = false;
bool hasError = false;
List<HotelPreview> hotels;
String errorMessage;
bool isGridViewOn = false;
bool isListViewOn = true;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState()
super.initState();
getDataDio();
List<Map<String, dynamic>> json = [
"uuid": "a9446b47-b0a1-454d-b89d-c3b848b7dc7c",
"name": "B&B-La-Fontaine",
"poster": "b&b_la_fontaine_1.jpg"
,
"uuid": "64f4ecc6-368e-414e-b6fe-8a059affe1ca",
"name": "Upon Lisbon Prime Residences",
"poster": "upon_lisbon_prime_residences_2.jpg"
,
"uuid": "82aded74-373e-4b9e-b721-ebb938e9ac19",
"name": "Disney Dreams",
"poster": "disney_dreams_1.jpg"
,
"uuid": "e08e35df-77a2-436a-9eb5-1dca46e0da00",
"name": "Flora Chiado Apartments",
"poster": "flora_chiado_apartments_1.jpg"
,
"uuid": "d782a2bf-1055-482a-9e3f-dffe25f023bd",
"name": "Golden Ratio",
"poster": "golden_ratio_1.jpg"
,
"uuid": "35344e37-ca0e-41a8-9c87-b13141d3e816",
"name": "Grand Orlando Resort",
"poster": "grand_orlando_resort_1.jpg"
,
"uuid": "0dd3c4e1-fb37-4348-aa06-7a2afc81c16a",
"name": "Holiday Inn & Suites Orlando",
"poster": "holiday_inn_&_suites_orlando_1.jpg"
,
"uuid": "3a4dea4b-17c2-4c5a-8cb2-556af5c7091b",
"name": "Motel One Brussels",
"poster": "motel_one_brussels_1.jpg"
,
"uuid": "ac1f829d-ffce-49d1-8ce6-9778559c98e5",
"name": "New Rome House",
"poster": "new_rome_house_1.jpg"
,
"uuid": "44c84d52-a815-40f6-a47c-1b8782b3de6e",
"name": "Oscar Hotel",
"poster": "oscar_hotel_1.jpg"
,
"uuid": "be338e29-d3dd-4298-924e-5604e8a7b350",
"name": "P 17 Hotel",
"poster": "p_17_hotel_1.jpg"
,
"uuid": "85af46cd-ed99-4c9f-ba22-6e34ea5bb8da",
"name": "Parkway International",
"poster": "parkway_international_1.jpg"
,
"uuid": "7fcd8e0c-fd4a-4146-bada-700e8790b69a",
"name": "Stradom Apartments",
"poster": "stradom_apartments_1.jpg"
,
"uuid": "b505a79c-0280-4a09-bba0-b984e1eed188",
"name": "Upon Lisbon Prime Residences",
"poster": "upon_lisbon_prime_residences_1.jpg"
];
getDataDio() async
setState(()
isLoading = true;
);
// try
// final response = await _dio
// .get('https://run.mocky.io/v3/ac888dc5-d193-4700-b12c-abb43e289301');
// var data = response.data;
// hotels = data
// .map<HotelPreview>(
// (hotelPreview) => HotelPreview.fromJson(hotelPreview))
// .toList();
// on DioError catch (e)
// setState(()
// errorMessage = e.response.data['message'];
// hasError = true;
// isLoading = false;
// );
//
final data = json;
hotels = data
.map<HotelPreview>(
(hotelPreview) => HotelPreview.fromJson(hotelPreview))
.toList();
setState(()
isLoading = false;
hasError = false;
);
@override
Widget build(BuildContext context)
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('Hotel Preview'),
actions: [
IconButton(
icon: const Icon(Icons.view_list),
onPressed: ()
setState(()
isListViewOn = !isListViewOn;
isGridViewOn = !isGridViewOn;
);
,
),
IconButton(
icon: const Icon(Icons.view_module),
onPressed: ()
setState(()
isListViewOn = !isListViewOn;
isGridViewOn = !isGridViewOn;
);
,
),
],
),
body: isLoading
? const Center(child: CircularProgressIndicator())
: hasError
? const Text('Page not found')
: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints)
return (isListViewOn && !isGridViewOn)
? ListView.builder(
itemCount: hotels.length,
itemBuilder: (context, index)
return ListTile(
leading: Text(hotels[index].uuid),
title: Text(hotels[index].name),
subtitle: Text(hotels[index].poster),
);
,
)
: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: hotels.length,
itemBuilder: (cpntext, index)
return GridTile(
header: Text(hotels[index].poster),
child: Text(hotels[index].uuid),
footer: Text(hotels[index].name),
);
,
);
,
),
);
class HotelPreview
String uuid;
String name;
String poster;
HotelPreview(this.uuid, this.name, this.poster);
HotelPreview.fromJson(Map<String, dynamic> json)
uuid = json['uuid'];
name = json['name'];
poster = json['poster'];
Map<String, dynamic> toJson()
final Map<String, dynamic> data = Map<String, dynamic>();
data['uuid'] = this.uuid;
data['name'] = this.name;
data['poster'] = this.poster;
return data;
【讨论】:
【参考方案2】:希望此参考资料能帮助您修改代码
带有构建器构造函数的列表视图
ListView.builder(
itemCount: 5,
itemBuilder: (BuildContext context,int index)
return ListTile(
leading: Icon(Icons.list),
trailing: Text("GFG",
style: TextStyle(
color: Colors.green,fontSize: 15),),
title:Text("List item $index")
);
)
带有构建器构造函数的Gridview
GridView.builder(
itemCount: images.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, crossAxisSpacing: 4.0, mainAxisSpacing: 4.0),
itemBuilder: (BuildContext context, int index)
return Image.network(images[index]);
,
)),
【讨论】:
以上是关于将 ListView 转换为 ListView.builder的主要内容,如果未能解决你的问题,请参考以下文章
Json 到 ListView - 无法将类型转换为 IEnumerable - Xamarin
带有子项的 Android ListView 导致无法将 TwoLineListItem 强制转换为 android.widget.TextView
如何在 Kotlin 中将 listView 转换为 RecyclerView