@@ -39,161 +39,152 @@ class _CameraExampleHomeState extends State<CameraExampleHome> {
39
39
40
40
@override
41
41
Widget build (BuildContext context) {
42
- final List <Widget > controlsChildren = < Widget > [];
43
- final List <Widget > cameraList = < Widget > [];
44
-
45
- if (cameras.isEmpty) {
46
- cameraList.add (const Text ('No camera found' ));
47
- } else {
48
- for (CameraDescription cameraDescription in cameras) {
49
- cameraList.add (
50
- new SizedBox (
51
- width: 90.0 ,
52
- child: new RadioListTile <CameraDescription >(
53
- title: new Icon (
54
- getCameraLensIcon (cameraDescription.lensDirection)),
55
- groupValue: controller? .description,
56
- value: cameraDescription,
57
- onChanged: (CameraDescription newValue) async =>
58
- onNewCameraSelected (newValue)),
59
- ),
60
- );
61
- }
62
- }
63
-
64
- // Add the cameras to the main controls widget.
65
- controlsChildren.add (new Row (children: cameraList));
66
-
67
- if (imagePath != null || videoController != null ) {
68
- controlsChildren.add (previewWidget ());
69
- }
70
-
71
- // Initialize the preview window
72
- final List <Widget > previewChildren = < Widget > [];
73
-
74
- // Depending on controller state display a message or the camera preview.
75
- if (controller == null || ! controller.value.isInitialized) {
76
- previewChildren.add (const Text (
77
- 'Tap a camera' ,
78
- style: const TextStyle (
79
- color: Colors .white,
80
- fontSize: 24.0 ,
81
- fontWeight: FontWeight .w900,
82
- ),
83
- ));
84
- } else if (controller.value.hasError) {
85
- previewChildren.add (
86
- new Text ('Camera error ${controller .value .errorDescription }' ),
87
- );
88
- } else {
89
- previewChildren.add (
90
- new Container (
91
- // Handle the preview depending on the aspect ratio of the camera view.
92
- child: new AspectRatio (
93
- aspectRatio: controller.value.aspectRatio,
94
- child: new CameraPreview (controller),
95
- ),
96
- height: (MediaQuery .of (context).size.height - 230.0 ),
97
- color: Colors .black,
98
- ),
99
- );
100
- }
101
-
102
42
// The main scaffolding of the app.
103
43
return new Scaffold (
104
44
key: _scaffoldKey,
105
45
appBar: new AppBar (
106
46
title: const Text ('Camera example' ),
107
47
),
108
48
body: new Column (children: < Widget > [
109
- new Container (
110
- child: new Padding (
111
- padding: const EdgeInsets .all (1.0 ),
112
- child: new Center (
113
- child: new Column (
114
- mainAxisAlignment: MainAxisAlignment .center,
115
- // Add the preview to the app.
116
- children: previewChildren,
49
+ new Expanded (
50
+ child: new Container (
51
+ child: new Padding (
52
+ padding: const EdgeInsets .all (1.0 ),
53
+ child: new Center (
54
+ child: _cameraPreviewWidget (),
117
55
),
118
56
),
119
- ),
120
- // Size of the container as wide as the device screen.
121
- width: MediaQuery .of (context).size.width,
122
- decoration: new BoxDecoration (
123
- color: Colors .black,
124
- border: new Border .all (
125
- color: controller != null && controller.value.isRecordingVideo
126
- ? Colors .redAccent
127
- : Colors .grey,
128
- width: 3.0 ,
57
+ decoration: new BoxDecoration (
58
+ color: Colors .black,
59
+ border: new Border .all (
60
+ color: controller != null && controller.value.isRecordingVideo
61
+ ? Colors .redAccent
62
+ : Colors .grey,
63
+ width: 3.0 ,
64
+ ),
129
65
),
130
66
),
131
67
),
132
68
new Padding (
133
69
padding: const EdgeInsets .all (5.0 ),
134
70
child: new Row (
135
71
mainAxisAlignment: MainAxisAlignment .start,
136
- // Add the controls to the app.
137
- children: controlsChildren),
72
+ children: < Widget > [
73
+ _cameraTogglesRowWidget (),
74
+ _thumbnailWidget (),
75
+ ]),
138
76
),
77
+ _captureControlRowWidget (),
139
78
]),
140
-
141
- // Bottom bar with the capture controls.
142
- bottomNavigationBar: (controller == null )
143
- ? null
144
- : new Row (
145
- mainAxisAlignment: MainAxisAlignment .spaceEvenly,
146
- mainAxisSize: MainAxisSize .max,
147
- children: < Widget > [
148
- new IconButton (
149
- icon: const Icon (Icons .camera_alt),
150
- color: Colors .blue,
151
- onPressed: controller.value.isInitialized &&
152
- ! controller.value.isRecordingVideo
153
- ? onTakePictureButtonPressed
154
- : null ,
155
- ),
156
- new IconButton (
157
- icon: const Icon (Icons .videocam),
158
- color: Colors .blue,
159
- onPressed: controller.value.isInitialized &&
160
- ! controller.value.isRecordingVideo
161
- ? onVideoRecordButtonPressed
162
- : null ,
163
- ),
164
- new IconButton (
165
- icon: const Icon (Icons .stop),
166
- color: Colors .red,
167
- onPressed: controller.value.isInitialized &&
168
- controller.value.isRecordingVideo
169
- ? onStopButtonPressed
170
- : null ,
171
- )
172
- ],
173
- ),
174
79
);
175
80
}
176
81
82
+ /// Display the preview from the camera (or a message if the preview is not available).
83
+ Widget _cameraPreviewWidget () {
84
+ if (controller == null || ! controller.value.isInitialized) {
85
+ return const Text (
86
+ 'Tap a camera' ,
87
+ style: const TextStyle (
88
+ color: Colors .white,
89
+ fontSize: 24.0 ,
90
+ fontWeight: FontWeight .w900,
91
+ ),
92
+ );
93
+ } else if (controller.value.hasError) {
94
+ return new Text ('Camera error ${controller .value .errorDescription }' );
95
+ } else {
96
+ return new AspectRatio (
97
+ aspectRatio: controller.value.aspectRatio,
98
+ child: new CameraPreview (controller),
99
+ );
100
+ }
101
+ }
102
+
177
103
/// Display the thumbnail of the captured image.
178
- Widget previewWidget () {
104
+ Widget _thumbnailWidget () {
179
105
return new Expanded (
180
106
child: new Align (
181
107
alignment: Alignment .centerRight,
182
- child: new SizedBox (
183
- child: (videoController == null )
184
- ? new Image .file (new File (imagePath))
185
- : new Container (
186
- child: new VideoPlayer (videoController),
187
- decoration: new BoxDecoration (
188
- border: new Border .all (color: Colors .pink)),
189
- ),
190
- width: 64.0 ,
191
- height: 64.0 ,
192
- ),
108
+ child: videoController == null && imagePath == null
109
+ ? null
110
+ : new SizedBox (
111
+ child: (videoController == null )
112
+ ? new Image .file (new File (imagePath))
113
+ : new Container (
114
+ child: new VideoPlayer (videoController),
115
+ decoration: new BoxDecoration (
116
+ border: new Border .all (color: Colors .pink)),
117
+ ),
118
+ width: 64.0 ,
119
+ height: 64.0 ,
120
+ ),
193
121
),
194
122
);
195
123
}
196
124
125
+ /// Display the control bar with buttons to take pictures and record videos.
126
+ Widget _captureControlRowWidget () {
127
+ return new Row (
128
+ mainAxisAlignment: MainAxisAlignment .spaceEvenly,
129
+ mainAxisSize: MainAxisSize .max,
130
+ children: < Widget > [
131
+ new IconButton (
132
+ icon: const Icon (Icons .camera_alt),
133
+ color: Colors .blue,
134
+ onPressed: controller != null &&
135
+ controller.value.isInitialized &&
136
+ ! controller.value.isRecordingVideo
137
+ ? onTakePictureButtonPressed
138
+ : null ,
139
+ ),
140
+ new IconButton (
141
+ icon: const Icon (Icons .videocam),
142
+ color: Colors .blue,
143
+ onPressed: controller != null &&
144
+ controller.value.isInitialized &&
145
+ ! controller.value.isRecordingVideo
146
+ ? onVideoRecordButtonPressed
147
+ : null ,
148
+ ),
149
+ new IconButton (
150
+ icon: const Icon (Icons .stop),
151
+ color: Colors .red,
152
+ onPressed: controller != null &&
153
+ controller.value.isInitialized &&
154
+ controller.value.isRecordingVideo
155
+ ? onStopButtonPressed
156
+ : null ,
157
+ )
158
+ ],
159
+ );
160
+ }
161
+
162
+ /// Display a row of toggle to select the camera (or a message if no camera is available).
163
+ Widget _cameraTogglesRowWidget () {
164
+ final List <Widget > toggles = < Widget > [];
165
+
166
+ if (cameras.isEmpty) {
167
+ return const Text ('No camera found' );
168
+ } else {
169
+ for (CameraDescription cameraDescription in cameras) {
170
+ toggles.add (
171
+ new SizedBox (
172
+ width: 90.0 ,
173
+ child: new RadioListTile <CameraDescription >(
174
+ title: new Icon (
175
+ getCameraLensIcon (cameraDescription.lensDirection)),
176
+ groupValue: controller? .description,
177
+ value: cameraDescription,
178
+ onChanged: (CameraDescription newValue) async =>
179
+ onNewCameraSelected (newValue)),
180
+ ),
181
+ );
182
+ }
183
+ }
184
+
185
+ return new Row (children: toggles);
186
+ }
187
+
197
188
String timestamp () => new DateTime .now ().millisecondsSinceEpoch.toString ();
198
189
199
190
void showInSnackBar (String message) {
0 commit comments