ListView.builder, ListTile और अपने-अपने विजेट में निकाले गए आइटम की बदौलत हज़ारों आइटम की सूचियाँ बिना किसी धीमेपन के प्रदर्शित करें।
इस पाठ को Kodokon में खोलेंएक वास्तविक ऐप लगभग हमेशा सूचियाँ प्रदर्शित करता है: संदेश, उत्पाद, संपर्क। ListView(children: ...) कंस्ट्रक्टर जिसे आप पहले से जानते हैं, अपने सभी चाइल्ड को एक साथ बनाता है - दस आइटम के लिए ठीक है, लेकिन एक हज़ार के लिए विनाशकारी। ListView.builder केवल दृश्य क्षेत्र के पास के आइटम बनाता है, माँग के अनुसार, जैसे-जैसे आप स्क्रॉल करते हैं।
import 'package:flutter/material.dart';
class ContactsScreen extends StatelessWidget {
const ContactsScreen({super.key, required this.names});
final List<String> names;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Contacts')),
body: ListView.builder(
itemCount: names.length,
itemBuilder: (context, index) {
return ListTile(
leading: const Icon(Icons.person),
title: Text(names[index]),
);
},
),
);
}
}दो पैरामीटर पूरे तंत्र को संभालते हैं: itemCount आइटम की कुल संख्या घोषित करता है, और itemBuilder किसी दिए गए इंडेक्स पर आइटम बनाता है, केवल तभी जब वह स्क्रीन के पास आता है। हर पंक्ति की सामग्री के लिए, ListTile आपका Material साथी है: leading, title, subtitle और trailing पंक्ति को संरचित करते हैं, और onTap छूने पर इंक रिपल प्रदान करता है। लेकिन जैसे ही कोई आइटम बड़ा होता है, उसे itemBuilder के अंदर फूलने न दें: उसे अपने खुद के विजेट में निकाल लें।
import 'package:flutter/material.dart';
class ContactTile extends StatelessWidget {
const ContactTile({
super.key,
required this.name,
required this.onTap,
});
final String name;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
return ListTile(
leading: CircleAvatar(child: Text(name[0])),
title: Text(name),
trailing: const Icon(Icons.chevron_right),
onTap: onTap,
);
}
}एक निकाला गया आइटम अलग से परीक्षण किया जा सकता है, दूसरी स्क्रीनों में पुनः प्रयोग किया जा सकता है, और itemBuilder को साधारण बना देता है। एक बार-बार आने वाली ज़रूरत बची रहती है: विभाजक (separator)। ListView.separated builder की तरह काम करता है, बस एक तीसरे पैरामीटर separatorBuilder के साथ, जिसे आइटम की हर जोड़ी के बीच कॉल किया जाता है - अंतिम तत्व के बाद कभी कोई विभाजक नहीं होता।
import 'package:flutter/material.dart';
class ContactList extends StatelessWidget {
const ContactList({super.key, required this.names});
final List<String> names;
@override
Widget build(BuildContext context) {
return ListView.separated(
itemCount: names.length,
separatorBuilder: (context, index) {
return const Divider(height: 1);
},
itemBuilder: (context, index) {
return ContactTile(
name: names[index],
onTap: () => debugPrint(names[index]),
);
},
);
}
}