Skip to content

[camera] 🐛 Fix toggles overflow in the camera example #9274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/camera/camera/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## NEXT

* Fixes overflowed toggles in the camera example.

## 0.11.1

* Adds API support query for image streaming.
Expand Down
72 changes: 35 additions & 37 deletions packages/camera/camera/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -225,43 +225,33 @@ class _CameraExampleHomeState extends State<CameraExampleHome>

/// Display the thumbnail of the captured image or video.
Widget _thumbnailWidget() {
final VideoPlayerController? localVideoController = videoController;

return Expanded(
child: Align(
alignment: Alignment.centerRight,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
if (localVideoController == null && imageFile == null)
Container()
else
SizedBox(
width: 64.0,
height: 64.0,
child: (localVideoController == null)
? (
// The captured image on the web contains a network-accessible URL
// pointing to a location within the browser. It may be displayed
// either with Image.network or Image.memory after loading the image
// bytes to memory.
kIsWeb
? Image.network(imageFile!.path)
: Image.file(File(imageFile!.path)))
: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.pink)),
child: Center(
child: AspectRatio(
aspectRatio:
localVideoController.value.aspectRatio,
child: VideoPlayer(localVideoController)),
),
),
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
if (videoController case final VideoPlayerController controller?)
Container(
width: 64.0,
height: 64.0,
decoration: BoxDecoration(border: Border.all(color: Colors.pink)),
child: Center(
child: AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: VideoPlayer(controller),
),
],
),
),
),
)
else if (imageFile?.path case final String path)
Container(
width: 64.0,
height: 64.0,
decoration: BoxDecoration(border: Border.all(color: Colors.pink)),
// The captured image on the web contains a network-accessible URL
// pointing to a location within the browser. It may be displayed
// either with Image.network or Image.memory after loading the image
// bytes to memory.
child: kIsWeb ? Image.network(path) : Image.file(File(path)),
),
],
);
}

Expand Down Expand Up @@ -598,7 +588,12 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
}
}

return Row(children: toggles);
return Expanded(
child: SizedBox(
height: 56.0,
child: ListView(scrollDirection: Axis.horizontal, children: toggles),
),
);
}

String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
Expand Down Expand Up @@ -1048,6 +1043,9 @@ class CameraApp extends StatelessWidget {
}
}

/// Getting available cameras for testing.
@visibleForTesting
List<CameraDescription> get cameras => _cameras;
List<CameraDescription> _cameras = <CameraDescription>[];

Future<void> main() async {
Expand Down
20 changes: 20 additions & 0 deletions packages/camera/camera/example/test/main_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:camera/camera.dart';
import 'package:camera_example/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
Expand All @@ -13,4 +14,23 @@ void main() {
await tester.pumpAndSettle();
expect(find.byType(SnackBar), findsOneWidget);
});

testWidgets(
'CameraDescription toggles will not overflow',
(WidgetTester tester) async {
WidgetsFlutterBinding.ensureInitialized();
// Adds 10 fake camera descriptions.
for (int i = 0; i < 10; i++) {
cameras.add(
CameraDescription(
name: 'camera_$i',
lensDirection: CameraLensDirection.back,
sensorOrientation: 90,
),
);
}
await tester.pumpWidget(const CameraApp());
await tester.pumpAndSettle();
},
);
}