Skip to content

Commit

Permalink
#19: Implement image carousel with fullscreen photo view.
Browse files Browse the repository at this point in the history
  • Loading branch information
hjtappe committed Dec 10, 2024
1 parent 698034c commit 18b4b65
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 13 deletions.
29 changes: 29 additions & 0 deletions lib/components/full_screen_image.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';

class FullScreenImage extends StatelessWidget {
final String imageUrl;

const FullScreenImage({
super.key,
required this.imageUrl,
});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Full Screen Image'),
),
body: PhotoView.customChild(
child: CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (context, url) => const CircularProgressIndicator(),
errorWidget: (context, url, error) => const Icon(Icons.error),
fit: BoxFit.contain,
),
),
);
}
}
91 changes: 91 additions & 0 deletions lib/components/image_carousel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:dots_indicator/dots_indicator.dart';
import 'package:flutter/material.dart';
import 'package:iccm_eu_app/components/full_screen_image.dart';

class ImageCarousel extends StatefulWidget {
final List<String> imageUrls;

const ImageCarousel({
super.key,
required this.imageUrls,
});

@override
ImageCarouselState createState() => ImageCarouselState();
}

class ImageCarouselState extends State<ImageCarousel> {
int _currentIndex = 0;

@override
Widget build(BuildContext context) {
if (widget.imageUrls.isEmpty) {
return SizedBox.shrink();
} else {
return Column(
children: [
CarouselSlider(
options: CarouselOptions(
height: 200, // Adjust height as needed
viewportFraction: 1.0, // Display one image at a time
onPageChanged: (index, reason) {
setState(() {
_currentIndex = index;
});
},
),
items: widget.imageUrls.map((imageUrl) {
return Builder(
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FullScreenImage(
imageUrl: imageUrl,
),
),
);
},
child: Container(
width: MediaQuery
.of(context)
.size
.width,
margin: const EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
),
child: CachedNetworkImage(
imageUrl: imageUrl,
// imageBuilder: (context, imageProvider) => CircleAvatar(
// backgroundImage: imageProvider,
// radius: 50,
// ),
placeholder: (context, url) => const CircularProgressIndicator(),
errorWidget: (context, url, error) => const Icon(Icons.error),
fit: BoxFit.cover,
),
),
);
},
);
}).toList(),
),
const SizedBox(height: 10), // Spacing between carousel and dots
DotsIndicator(
dotsCount: widget.imageUrls.length,
position: _currentIndex,
decorator: DotsDecorator(
color: Colors.grey, // Inactive dot color
activeColor: Colors.blue, // Active dot color
),
),
],
);
}
}
}
6 changes: 6 additions & 0 deletions lib/data/model/room_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,22 @@ class RoomData extends ModelItem {
final String name;
@override
final String details;
String? mapImageUrl;
late ColorsData? colors;

RoomData({
required this.imageUrl,
required this.name,
required this.details,
this.mapImageUrl,
this.colors,
});

RoomData._({
required this.imageUrl,
required this.name,
required this.details,
this.mapImageUrl,
this.colors,
});

Expand All @@ -30,6 +33,7 @@ class RoomData extends ModelItem {
imageUrl: UrlFunctions.proxy(itemData['Photo 1']),
name: itemData['Name'] ?? '',
details: itemData['Description'] ?? '',
mapImageUrl: UrlFunctions.proxy(itemData['Photo 2']),
colors: null,
);
}
Expand All @@ -40,6 +44,7 @@ class RoomData extends ModelItem {
imageUrl: json['imageUrl'],
name: json['name'] as String? ?? '',
details: json['details'] as String? ?? '',
mapImageUrl: json['details'] as String? ?? '',
);
}

Expand All @@ -48,6 +53,7 @@ class RoomData extends ModelItem {
'imageUrl': imageUrl,
'name': name.toString(),
'details': details.toString(),
'mapImageUrl': mapImageUrl.toString()
};
}
}
23 changes: 10 additions & 13 deletions lib/pages/room_details_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:iccm_eu_app/components/event_list_tile.dart';
import 'package:iccm_eu_app/components/image_carousel.dart';
import 'package:iccm_eu_app/controls/nav_bar.dart';
import 'package:iccm_eu_app/data/dataProviders/events_provider.dart';
import 'package:iccm_eu_app/data/model/event_data.dart';
Expand All @@ -23,6 +23,14 @@ class RoomDetailsPage extends StatelessWidget {
List<EventData> listItems = eventsProvider.eventsByRoom(
name: item.name,
);
List<String> imageUrls = [];
if (item.imageUrl.startsWith('https://')) {
imageUrls.add(item.imageUrl);
}
if (item.mapImageUrl != null &&
item.mapImageUrl!.startsWith('https://')) {
imageUrls.add(item.mapImageUrl ?? '');
}
return Scaffold(
appBar: AppBar(
title: const Text("Room Details"),
Expand All @@ -36,18 +44,7 @@ class RoomDetailsPage extends StatelessWidget {
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (item.imageUrl.startsWith("http"))
CachedNetworkImage(
imageUrl: item.imageUrl,
imageBuilder: (context, imageProvider) => CircleAvatar(
backgroundImage: imageProvider,
radius: 50,
),
placeholder: (context, url) => const CircularProgressIndicator(),
errorWidget: (context, url, error) => const Icon(Icons.error),
)
else
const SizedBox.shrink(),
ImageCarousel(imageUrls: imageUrls),
const SizedBox(height: 16),
Text(item.name,
style: Theme.of(context).textTheme.headlineSmall,
Expand Down
24 changes: 24 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.1"
carousel_slider:
dependency: "direct main"
description:
name: carousel_slider
sha256: "7b006ec356205054af5beaef62e2221160ea36b90fb70a35e4deacd49d0349ae"
url: "https://pub.dev"
source: hosted
version: "5.0.0"
characters:
dependency: transitive
description:
Expand Down Expand Up @@ -137,6 +145,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.10"
dots_indicator:
dependency: "direct main"
description:
name: dots_indicator
sha256: "58b6a365744aa62aa1b70c4ea29e5106fbe064f5edaf7e9652e9b856edbfd9bb"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
fake_async:
dependency: transitive
description:
Expand Down Expand Up @@ -472,6 +488,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.0.2"
photo_view:
dependency: "direct main"
description:
name: photo_view
sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e"
url: "https://pub.dev"
source: hosted
version: "0.15.0"
platform:
dependency: transitive
description:
Expand Down
3 changes: 3 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ dependencies:
flutter_local_notifications: ^18.0.1
firebase_core: ^3.8.0
firebase_messaging: ^15.1.5
carousel_slider: ^5.0.0
dots_indicator: ^3.0.0
photo_view: ^0.15.0

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 18b4b65

Please sign in to comment.