horizontalListView method
Creates a horizontal scrolling list view for image attachments.
Displays a horizontally scrollable gallery of images with tap-to-fullscreen functionality
and optional delete buttons. Requires attachments with contentType, contentUrl, and id properties.
Parameters:
attachments: List of attachment objects containing image data.maxWidth: Maximum width for each image card (defaults to 200).maxHeight: Maximum height for each image card (defaults to 300).horizontalMargin: Horizontal margin between images (defaults to 5).borderRadius: Corner radius for image cards (defaults to 15).onItemTap: Optional callback when an item is tapped.isDeleteShow: Whether to show delete buttons on images (defaults to false).
Returns a horizontal ListView.builder or empty Container if no attachments.
Features:
- Displays only image attachments (checks
contentType.contains("image")) - Opens fullscreen view on tap using FullScreenImage dialog
- Uses Hero animations for smooth transitions
- Optional delete functionality that removes items from the list
- Network image caching with specified dimensions
Note: Each attachment must have:
contentType: String indicating file type (e.g., "image/jpeg")contentUrl: String URL of the imageid: Unique identifier for Hero animation
Example:
horizontalListView(
attachmentsList,
maxWidth: 250,
maxHeight: 350,
borderRadius: 20,
isDeleteShow: true,
);
Implementation
Widget horizontalListView(List<dynamic> attachments,
{double maxWidth = 200,
double maxHeight = 300,
double horizontalMargin = 5,
double borderRadius = 15,
Function(dynamic)? onItemTap,
bool? isDeleteShow = false}) {
return attachments.isNotEmpty
? SizedBox(
height: 200, // Set height of the container to display the images
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: attachments.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () {
if (attachments[index].contentType!.contains("image")) {
Get.dialog(FullScreenImage(
url: attachments[index].contentUrl!,
heroTag: "imageTag${attachments[index].id}",
));
}
}, // onItemTap != null ? onItemTap(attachments[index]) : "",
child: Stack(children: [
Card(
elevation: 4,
child: Container(
constraints: BoxConstraints(
maxWidth: maxWidth, // Image width
maxHeight: maxHeight,
),
margin: EdgeInsets.symmetric(
horizontal: horizontalMargin),
child: ClipRRect(
borderRadius: BorderRadius.circular(
borderRadius), // Rounded corners
child: Hero(
tag: "imageTag${attachments[index].id}",
child: attachments[index]
.contentType!
.contains("image")
? Image.network(
cacheWidth: maxWidth.toInt(),
cacheHeight: maxHeight.toInt(),
attachments[index].contentUrl!,
fit: BoxFit.cover,
)
: Container(),
),
),
),
),
if (isDeleteShow == true)
Positioned(
top: 0,
right: 0,
child: IconButton(
icon: const Icon(Icons.close,
color: Colors.black, size: 30),
onPressed: () {
attachments.removeAt(index);
},
),
)
]),
),
);
},
),
)
: Container();
}