Skip to content

Commit c12134c

Browse files
committed
Fullscreen image preview (with also zoom)
1 parent 3b77f77 commit c12134c

7 files changed

+223
-39
lines changed

lib/main.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'package:flutter/material.dart';
2-
import 'pages/plants_list/plants_list.dart';
2+
import 'pages/plants_list/plants_list_page.dart';
33
import 'package:flutter/services.dart';
44

55
void main() => runApp(new MyApp());

lib/pages/fullscreen_image_page.dart

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import 'package:flutter/material.dart';
2+
import 'image_zoomable.dart';
3+
4+
class FullscreenImagePage extends StatelessWidget
5+
{
6+
final String imgPath;
7+
FullscreenImagePage(this.imgPath);
8+
9+
final LinearGradient backgroundGradient = new LinearGradient
10+
(
11+
colors:
12+
[
13+
new Color(0x10000000), // Light black
14+
new Color(0x30000000), // Dark black
15+
],
16+
begin: Alignment.topLeft,
17+
end: Alignment.bottomRight
18+
);
19+
20+
@override
21+
Widget build(BuildContext context)
22+
{
23+
return new Scaffold
24+
(
25+
body: new SizedBox.expand
26+
(
27+
child: new Container
28+
(
29+
decoration: new BoxDecoration
30+
(
31+
gradient: backgroundGradient
32+
),
33+
child: new Stack
34+
(
35+
children: <Widget>
36+
[
37+
new Align
38+
(
39+
alignment: Alignment.center,
40+
child: new Hero
41+
(
42+
tag: imgPath,
43+
child: new Image.asset(imgPath),
44+
),
45+
),
46+
new Align
47+
(
48+
alignment: Alignment.topCenter,
49+
child: new Column
50+
(
51+
// I need to add a column to set the MainAxisSize to min,
52+
// otherwise the appbar takes all the screen and the image is no more clickable
53+
mainAxisAlignment: MainAxisAlignment.start,
54+
mainAxisSize: MainAxisSize.min,
55+
children: <Widget>
56+
[
57+
new AppBar
58+
(
59+
elevation: 0.0,
60+
backgroundColor: Colors.transparent,
61+
leading: new IconButton
62+
(
63+
onPressed: () => Navigator.of(context).pop(),
64+
icon: new Icon(Icons.close, color: Colors.black),
65+
),
66+
actions: <Widget>
67+
[
68+
new IconButton
69+
(
70+
onPressed: () => Navigator.of(context).push(new MaterialPageRoute(builder: (_) => new ImageZoomable(imgPath))),
71+
icon: new Icon(Icons.zoom_in, color: Colors.black),
72+
),
73+
],
74+
),
75+
],
76+
),
77+
),
78+
],
79+
)
80+
),
81+
),
82+
);
83+
}
84+
}

lib/pages/image_zoomable.dart

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:zoomable_image/zoomable_image.dart';
3+
4+
class ImageZoomable extends StatelessWidget
5+
{
6+
final String imgPath;
7+
ImageZoomable(this.imgPath);
8+
9+
@override
10+
Widget build(BuildContext context)
11+
{
12+
return new Scaffold
13+
(
14+
backgroundColor: Colors.transparent,
15+
body: new SizedBox.expand
16+
(
17+
child: new Stack
18+
(
19+
children: <Widget>
20+
[
21+
new Align
22+
(
23+
alignment: Alignment.center,
24+
child: new Hero
25+
(
26+
tag: imgPath,
27+
child: new ZoomableImage(new AssetImage(imgPath), scale: 5.0),
28+
),
29+
),
30+
new Align
31+
(
32+
alignment: Alignment.topCenter,
33+
child: new Column
34+
(
35+
// I need to add a column to set the MainAxisSize to min,
36+
// otherwise the appbar takes all the screen and the image is no more clickable
37+
mainAxisAlignment: MainAxisAlignment.start,
38+
mainAxisSize: MainAxisSize.min,
39+
children: <Widget>
40+
[
41+
new AppBar
42+
(
43+
elevation: 0.0,
44+
backgroundColor: Colors.transparent,
45+
actions: <Widget>
46+
[
47+
new IconButton
48+
(
49+
onPressed: () => Navigator.of(context).pop(),
50+
icon: new Icon(Icons.close, color: Colors.white),
51+
),
52+
],
53+
),
54+
],
55+
),
56+
),
57+
],
58+
),
59+
),
60+
);
61+
}
62+
}

lib/pages/plants_list/plant_preview.dart

+68-38
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,95 @@
11
import 'package:flutter/material.dart';
22
import '../../classes/plant.dart';
3+
import '../fullscreen_image_page.dart';
34

45
class PlantPreview extends StatelessWidget
56
{
67
final Plant plant;
78
PlantPreview(this.plant);
89

10+
final LinearGradient backgroundGradient = new LinearGradient
11+
(
12+
colors:
13+
[
14+
new Color(0x10000000), // Light black
15+
new Color(0x30000000), // Dark black
16+
],
17+
begin: Alignment.topLeft,
18+
end: Alignment.bottomRight
19+
);
20+
921
@override
1022
Widget build(BuildContext context)
1123
{
1224
return new Padding
1325
(
1426
padding: const EdgeInsets.only(top: 24.0, left: 24.0, right: 24.0, bottom: 0.0),
15-
child: new Material
27+
child: new GestureDetector
1628
(
17-
borderRadius: new BorderRadius.circular(14.0),
18-
color: Colors.black12,
19-
child: new Stack
29+
onTap: () => Navigator.of(context).push(new MaterialPageRoute(builder: (_) => new FullscreenImagePage('res/' + plant.plantImg))),
30+
child: new Material
2031
(
21-
children: <Widget>
22-
[
23-
new Align
24-
(
25-
alignment: Alignment.center,
26-
child: new Image.asset('res/${plant.plantImg}')
27-
),
28-
new Align
29-
(
30-
alignment: Alignment.bottomLeft,
31-
child: new Material
32+
borderRadius: new BorderRadius.circular(14.0),
33+
color: Colors.transparent,
34+
child: new Stack
35+
(
36+
children: <Widget>
37+
[
38+
new SizedBox.expand
3239
(
33-
borderRadius: new BorderRadius.only(topRight: new Radius.circular(14.0)),
34-
color: Colors.black,
3540
child: new Container
3641
(
37-
margin: new EdgeInsets.all(12.0),
38-
child: new Text(plant.plantName, style: new TextStyle(color: Colors.white, fontSize: 24.0, fontWeight: FontWeight.w700)),
42+
decoration: new BoxDecoration
43+
(
44+
gradient: backgroundGradient
45+
),
3946
),
40-
)
41-
),
42-
new Align
43-
(
44-
alignment: Alignment.topRight,
45-
child: new Material
47+
),
48+
new Align
4649
(
47-
borderRadius: new BorderRadius.only(bottomLeft: new Radius.circular(14.0)),
48-
color: Colors.green,
49-
child: new Container
50+
alignment: Alignment.center,
51+
child: new Hero
52+
(
53+
tag: 'res/' + plant.plantImg,
54+
child: new Image.asset('res/${plant.plantImg}')
55+
)
56+
),
57+
new Align
58+
(
59+
alignment: Alignment.bottomLeft,
60+
child: new Material
5061
(
51-
margin: new EdgeInsets.all(12.0),
52-
child: new Text
62+
borderRadius: new BorderRadius.only(topRight: new Radius.circular(14.0)),
63+
color: Colors.black,
64+
child: new Container
5365
(
54-
plant.price - plant.price.truncate() > 0
55-
? '\$${plant.price.toStringAsFixed(2)}'
56-
: '\$${plant.price.truncate()}',
57-
style: new TextStyle(color: Colors.white, fontSize: 22.0, fontWeight: FontWeight.w500)
66+
margin: new EdgeInsets.all(12.0),
67+
child: new Text(plant.plantName, style: new TextStyle(color: Colors.white, fontSize: 24.0, fontWeight: FontWeight.w700)),
5868
),
59-
),
60-
)
61-
),
62-
],
69+
)
70+
),
71+
new Align
72+
(
73+
alignment: Alignment.topRight,
74+
child: new Material
75+
(
76+
borderRadius: new BorderRadius.only(bottomLeft: new Radius.circular(14.0)),
77+
color: Colors.green,
78+
child: new Container
79+
(
80+
margin: new EdgeInsets.all(12.0),
81+
child: new Text
82+
(
83+
plant.price - plant.price.truncate() > 0
84+
? '\$${plant.price.toStringAsFixed(2)}'
85+
: '\$${plant.price.truncate()}',
86+
style: new TextStyle(color: Colors.white, fontSize: 22.0, fontWeight: FontWeight.w500)
87+
),
88+
),
89+
)
90+
),
91+
],
92+
),
6393
),
6494
),
6595
);

pubspec.lock

+7
Original file line numberDiff line numberDiff line change
@@ -394,5 +394,12 @@ packages:
394394
url: "https://pub.dartlang.org"
395395
source: hosted
396396
version: "2.1.13"
397+
zoomable_image:
398+
dependency: "direct main"
399+
description:
400+
name: zoomable_image
401+
url: "https://pub.dartlang.org"
402+
source: hosted
403+
version: "1.1.2"
397404
sdks:
398405
dart: ">=2.0.0-dev.23.0 <=2.0.0-edge.3c4dccbd46f152be9e1b6ca95c57357e8e48057c"

pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dependencies:
88
# The following adds the Cupertino Icons font to your application.
99
# Use with the CupertinoIcons class for iOS style icons.
1010
cupertino_icons: ^0.1.0
11+
zoomable_image: "^1.1.2"
1112

1213
dev_dependencies:
1314
flutter_test:

0 commit comments

Comments
 (0)