What is a Listview?
In the default constructor of the ListView class. A ListView simply takes a list of widgets and makes it scrollable. Usually, this is used with a few children as the List will also construct invisible elements in the list, so numerous widgets may render this inefficiently. In simple words, ListView is used to group several items in an array and display them in a scrollable list. The list can be scrolled vertically, or horizontally.
Single Screen with search
Properties of ListView Widget:
- childrenDelegate: This property takes SliverChildDelegate as the object. It serves as a delegate that provided the children for the ListView.(Delegate that provides the children the ListView.)
- clipBehaviour: This property holds Clip enum (final) as the object. It controls whether the content in the ListView will be clipped or not. (The content will be clipped (or not) according to this option.)
- itemExtent: The itemExtent takes in a double value as the object to control the scrollable area in the ListView.(If non-null, forces the children to have the given extent in the scroll direction.)
- padding: It holds EdgeInsetsGeometryI as the object to give space between the Listview and its children. (When passing layout constraints to its child, padding shrinks the constraints by the given padding, causing the child to layout at a smaller size. Padding then sizes itself to its child’s size, inflated by the padding, effectively creating empty space around the child.)
- scrollDirection: This property takes in the Axis enum as the object to decide the direction of the scroll on the ListView.
- shrinkWrap: This property takes in a boolean value as the object to decide whether the size of the scrollable area will be determined by the contents inside the ListView.
- createElement: Creates a StatelessElement to manage this widget’s location in the tree.
Environment
- 1.71.0 (Universal)
- Dart Programming
- Flutter 3.0.5+ Version
- Build iOS
- Build Android
- Run iPhone 11 Pro
- Android SDK
- XCODE
- CMD (on Windows) or Terminal Terminal (on Mac/Linux)
- IDE (Android Studio/IntelliJ/Visual Studio Code)
Features structure
- block pattern structure
- data model and user default
- Delegate pass value
- ListView UI Design
- Widgets
- Button
- check box
- search box
Pods(Pub.dev)
- path_provider: ^2.0.8
- shared_preferences: ^2.0.7
- fluttertoast: ^8.0.8
- flutter_spinkit: ^5.1.0
- intl_utils: ^2.7.0
- package_info: ^2.0.0
- permission_handler: ^6.0.1+1
- google_fonts: ^2.1.0
- progress_dialog_null_safe: ^1.0.6
Let’s get started on the main steps!
Model class – have created a model class name as a CropList
class CropList {
final String cropName;
final String description;
final String cropUrl;
CropList(
this.cropName,
this.description,
this.cropUrl,
);
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is CropList &&
runtimeType == other.runtimeType &&
cropUrl == other.cropUrl;
@override
int get hashCode => cropUrl.hashCode;
}
Create a constructor of the array
List<CropList> natureList = [
CropList("Apple", "Apple",
"https://secure.gravatar.com/avatar/4c5903769f71b03b49bb6e1d6c511eee?s=64&d=identicon&r=g"),
CropList("Cucumber", "Cucumber",
"https://secure.gravatar.com/avatar/4c5903769f71b03b49bb6e1d6c511eee?s=64&d=identicon&r=g"),
CropList("Paddy", "Paddy",
"https://secure.gravatar.com/avatar/4c5903769f71b03b49bb6e1d6c511eee?s=64&d=identicon&r=g"),
CropList("Coconut", "Coconut",
"https://secure.gravatar.com/avatar/4c5903769f71b03b49bb6e1d6c511eee?s=64&d=identicon&r=g"),
];
HashSet<CropList> selectedItem = HashSet();
bool isMultiSelectionEnabled = true;
ListView creates a card and binds the dynamically with the map method with module data binding a list
Expanded(
child: ListView(
children: cropList.map((CropList croplist) {
return Card(
color: AppColors.listRowColor,
elevation: 20,
margin:
const EdgeInsets.only(left: 10, right: 10, top: 5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)),
child: Container(
margin: const EdgeInsets.only(
left: 10, right: 10, top: 2, bottom: 5),
height: 40.0,
child: getCropListItem(croplist),
));
}).toList(),
),
),
Bottom navigation bar button
bottomNavigationBar: Container(
height: 65,
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: const BoxDecoration(
color: AppColors.mainBg,
),
child: Center(
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Text(isMultiSelectionEnabled
? getSelectedItemCount()
: "crop (s) selected"),
),
zconst SizedBox(
height: 5,
),
],
),
const Spacer(),
SizedBox(
width: 150,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: AppColors.buttonColor,
textStyle:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
onPressed: () {
//next screen to go
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
MyHomePage()));
},
child: Text('Select'),
),
),
],
),
),
),
MultiSelection function in ListView
String getSelectedItemCount() {
return selectedItem.isNotEmpty
? selectedItem.length.toString() + " crop (s) selected"
: "No crop selected";
}
void doMultiSelection(CropList croplist) {
if (isMultiSelectionEnabled) {
if (selectedItem.contains(croplist)) {
selectedItem.remove(croplist);
} else {
selectedItem.add(croplist);
}
setState(() {});
} else {
//Other logic create hear
}
}
listview bind code (this function creates a Visibility of the check box show and hide of the check box)
InkWell getCropListItem(CropList croplist) {
return InkWell(
onTap: () {
isMultiSelectionEnabled = true;
doMultiSelection(croplist);
},
onLongPress: () {
doMultiSelection(croplist);
},
child: Stack(alignment: Alignment.centerLeft, children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(
height: 10,
),
SizedBox(
width: double.infinity,
height: 18.0,
child: Padding(
padding: const EdgeInsets.only(left: 40.0),
child: Padding(
padding: const EdgeInsets.only(top: 1.0),
child: Text(
croplist.cropName,
style: TextStyle(
fontSize: 15,
fontFamily: 'Poppins',
fontStyle: FontStyle.normal,
color: AppColors.textRegColor,
),
),
),
),
),
],
),
)
],
),
Visibility(
visible: isMultiSelectionEnabled,
child: Icon(
selectedItem.contains(croplist)
? Icons.check_box
: Icons.check_box_outline_blank,
size: 30,
color: AppColors.blueColor,
))
]));
}
Search box UI code in a flutter
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TextField(
onChanged: (value) {
setState(() {
// searchString = value.toLowerCase();
});
},
decoration: InputDecoration(
labelText: 'Search Crop',
prefixIcon: Icon(Icons.search),
contentPadding: EdgeInsets.fromLTRB(8, 5, 10, 5),
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(2.0),
),
),
),
),
SizedBox(height: 10),
full code UI and all functions with OUTPUT
import 'package:flutter/material.dart';
import 'dart:collection';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:securisk_app/mainapp/policy_registration.dart';
import 'package:securisk_app/mainapp/reg.dart';
import 'package:securisk_app/utlity/colors.dart';
class MultiSelectCrop extends StatefulWidget {
const MultiSelectCrop({Key? key}) : super(key: key);
@override
_MultiSelectCropState createState() => new _MultiSelectCropState();
}
class _MultiSelectCropState extends State<MultiSelectCrop> {
List<CropList> cropList = [
CropList("Apple", "Apple",
"https://secure.gravatar.com/avatar/4c5903769f71b03b49bb6e1d6c511eee?s=64&d=identicon&r=g"),
CropList("Cucumber", "Cucumber",
"https://secure.gravatar.com/avatar/4c5903769f71b03b49bb6e1d6c511eee?s=64&d=identicon&r=g"),
CropList("Paddy", "Paddy",
"https://secure.gravatar.com/avatar/4c5903769f71b03b49bb6e1d6c511eee?s=64&d=identicon&r=g"),
CropList("Coconut", "Coconut",
"https://secure.gravatar.com/avatar/4c5903769f71b03b49bb6e1d6c511eee?s=64&d=identicon&r=g"),
];
HashSet<CropList> selectedItem = HashSet();
bool isMultiSelectionEnabled = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: AppColors.headerColor,
// centerTitle: isMultiSelectionEnabled ? false : true,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => Navigator.of(context).pop(),
),
elevation: 0,
),
body: Container(
color: AppColors.mainBg,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TextField(
onChanged: (value) {
setState(() {
// searchString = value.toLowerCase();
});
},
decoration: InputDecoration(
labelText: 'Search Crop',
prefixIcon: Icon(Icons.search),
contentPadding: EdgeInsets.fromLTRB(8, 5, 10, 5),
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(2.0),
),
),
),
),
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(left: 13.0, bottom: 4),
child: InkWell(
child: SizedBox(
height: 20,
child: SvgPicture.asset("assets/images/sort.svg",
fit: BoxFit.scaleDown),
),
onTap: () {}),
),
Expanded(
child: ListView(
children: cropList.map((CropList croplist) {
return Card(
color: AppColors.listRowColor,
elevation: 20,
margin:
const EdgeInsets.only(left: 10, right: 10, top: 5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)),
child: Container(
margin: const EdgeInsets.only(
left: 10, right: 10, top: 2, bottom: 5),
height: 40.0,
child: getCropListItem(croplist),
));
}).toList(),
),
),
],
),
),
bottomNavigationBar: Container(
height: 65,
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: const BoxDecoration(
color: AppColors.mainBg,
),
child: Center(
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Text(isMultiSelectionEnabled
? getSelectedItemCount()
: "crop (s) selected"),
),
const SizedBox(
height: 5,
),
],
),
const Spacer(),
SizedBox(
width: 150,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: AppColors.buttonColor,
textStyle:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
MyHomePage()));
},
child: Text('Select'),
),
),
],
),
),
),
);
}
String getSelectedItemCount() {
return selectedItem.isNotEmpty
? selectedItem.length.toString() + " crop (s) selected"
: "No crop selected";
}
void doMultiSelection(CropList croplist) {
if (isMultiSelectionEnabled) {
if (selectedItem.contains(croplist)) {
selectedItem.remove(croplist);
} else {
selectedItem.add(croplist);
}
setState(() {});
} else {
//Other logic create hear
}
}
InkWell getCropListItem(CropList croplist) {
return InkWell(
onTap: () {
isMultiSelectionEnabled = true;
doMultiSelection(croplist);
},
onLongPress: () {
doMultiSelection(croplist);
},
child: Stack(alignment: Alignment.centerLeft, children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(
height: 10,
),
SizedBox(
width: double.infinity,
height: 18.0,
child: Padding(
padding: const EdgeInsets.only(left: 40.0),
child: Padding(
padding: const EdgeInsets.only(top: 1.0),
child: Text(
croplist.cropName,
style: TextStyle(
fontSize: 15,
fontFamily: 'Poppins',
fontStyle: FontStyle.normal,
color: AppColors.textRegColor,
),
),
),
),
),
],
),
)
],
),
Visibility(
visible: isMultiSelectionEnabled,
child: Icon(
selectedItem.contains(croplist)
? Icons.check_box
: Icons.check_box_outline_blank,
size: 30,
color: AppColors.blueColor,
))
]));
}
}
App Colors class
import 'package:flutter/material.dart';
class AppColors {
static final Color spleshColor = Color(0XFFDEDEDE);
static const headerColor = Color(0xFF1D4380);
static const mainBg = Color(0xFFFAFEFE);
static final Color blueColor = Color(0XFF0c99c3);
static const textRegColor = Color(0xFF1D4380);
}
I hope you enjoyed reading this article and implementing some tricks in your next project. See you soon.