From 61d54ac088c8e0b113d1822b158d379b95f37fee Mon Sep 17 00:00:00 2001 From: Alex Li Date: Thu, 17 Aug 2023 13:39:18 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8=20Adapt=20device=20orientation=20l?= =?UTF-8?q?ayouts=20(#185)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 +++ guides/migration_guide.md | 11 ++++ lib/src/states/camera_picker_state.dart | 68 +++++++++++++++++++++---- pubspec.yaml | 2 +- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ff394d..49efb4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ that can be found in the LICENSE file. --> See the [Migration Guide](guides/migration_guide.md) for the details of breaking changes between versions. +## 4.0.0-dev.3 + +### Improvements + +- Adapt layouts according to the device orientation. + ## 4.0.0-dev.2 ### New features diff --git a/guides/migration_guide.md b/guides/migration_guide.md index 71bd17a..24d23b6 100644 --- a/guides/migration_guide.md +++ b/guides/migration_guide.md @@ -24,6 +24,7 @@ few naming or signatures of methods are changed. including: - `buildCameraPreview` - `buildCaptureButton` - `buildFocusingPoint` +- `buildForegroundBody` ### Details @@ -53,3 +54,13 @@ few naming or signatures of methods are changed. including: int quarterTurns = 0, }) ``` +- `buildForegroundBody` now adds `DeviceOrientation? deviceOrientation` + to make responsive layouts according to the device orientation. + So the signature becomes: + ```dart + Widget buildForegroundBody( + BuildContext context, + BoxConstraints constraints, + DeviceOrientation? deviceOrientation, + ) + ``` diff --git a/lib/src/states/camera_picker_state.dart b/lib/src/states/camera_picker_state.dart index 89f5afc..06b459b 100644 --- a/lib/src/states/camera_picker_state.dart +++ b/lib/src/states/camera_picker_state.dart @@ -956,11 +956,13 @@ class CameraPickerState extends State child: flashModeSwitch, ); } + final isPortrait = v.deviceOrientation.toString().contains('portrait'); return Padding( padding: const EdgeInsets.symmetric(horizontal: 12), - child: Row( + child: Flex( + direction: isPortrait ? Axis.horizontal : Axis.vertical, children: [ - if (innerController?.value.isRecordingVideo != true) backButton, + if (!v.isRecordingVideo) backButton, const Spacer(), flashModeSwitch, ], @@ -1055,9 +1057,17 @@ class CameraPickerState extends State required BoxConstraints constraints, CameraController? controller, }) { + final orientation = controller?.value.deviceOrientation ?? + MediaQuery.of(context).orientation; + final isPortrait = orientation.toString().contains('portrait'); return SizedBox( - height: 118, - child: Row( + width: isPortrait ? null : 118, + height: isPortrait ? 118 : null, + child: Flex( + direction: isPortrait ? Axis.horizontal : Axis.vertical, + verticalDirection: orientation == DeviceOrientation.landscapeLeft + ? VerticalDirection.up + : VerticalDirection.down, children: [ const Spacer(), Expanded( @@ -1268,7 +1278,8 @@ class CameraPickerState extends State Widget buildFromPoint(Offset point) { const double controllerWidth = 20; - final double pointWidth = constraints.maxWidth / 5; + final double pointWidth = + math.min(constraints.maxWidth, constraints.maxHeight) / 5; final double lineHeight = pointWidth * 2.5; final double exposureControlWidth = pickerConfig.enableExposureControlOnPoint ? controllerWidth : 0; @@ -1437,7 +1448,12 @@ class CameraPickerState extends State child: RotatedBox( quarterTurns: cameraQuarterTurns, child: Align( - alignment: Alignment.bottomCenter, + alignment: { + DeviceOrientation.portraitUp: Alignment.bottomCenter, + DeviceOrientation.portraitDown: Alignment.topCenter, + DeviceOrientation.landscapeLeft: Alignment.centerRight, + DeviceOrientation.landscapeRight: Alignment.centerLeft, + }[cameraValue.deviceOrientation]!, child: buildCaptureTips(innerController), ), ), @@ -1497,11 +1513,24 @@ class CameraPickerState extends State ); } - Widget buildForegroundBody(BuildContext context, BoxConstraints constraints) { + Widget buildForegroundBody( + BuildContext context, + BoxConstraints constraints, + DeviceOrientation? deviceOrientation, + ) { + final orientation = deviceOrientation ?? MediaQuery.of(context).orientation; + final isPortrait = orientation.toString().contains('portrait'); return SafeArea( child: Padding( padding: const EdgeInsets.only(bottom: 20), - child: Column( + child: Flex( + direction: isPortrait ? Axis.vertical : Axis.horizontal, + textDirection: orientation == DeviceOrientation.landscapeRight + ? TextDirection.rtl + : TextDirection.ltr, + verticalDirection: orientation == DeviceOrientation.portraitDown + ? VerticalDirection.up + : VerticalDirection.down, children: [ Semantics( sortKey: const OrdinalSortKey(0), @@ -1540,9 +1569,17 @@ class CameraPickerState extends State ); } return Align( - alignment: AlignmentDirectional.topCenter, + alignment: { + DeviceOrientation.portraitUp: Alignment.topCenter, + DeviceOrientation.portraitDown: Alignment.bottomCenter, + DeviceOrientation.landscapeLeft: Alignment.centerLeft, + DeviceOrientation.landscapeRight: Alignment.centerRight, + }[v.deviceOrientation]!, child: AspectRatio( - aspectRatio: 1 / v.aspectRatio, + aspectRatio: + v.deviceOrientation.toString().contains('portrait') + ? 1 / v.aspectRatio + : v.aspectRatio, child: LayoutBuilder( builder: (BuildContext c, BoxConstraints constraints) { return buildCameraPreview( @@ -1602,7 +1639,16 @@ class CameraPickerState extends State pickerConfig.foregroundBuilder!(context, innerController), ), ], - buildForegroundBody(context, constraints), + if (innerController == null) + buildForegroundBody(context, constraints, null) + else + buildInitializeWrapper( + builder: (CameraValue v, _) => buildForegroundBody( + context, + constraints, + v.deviceOrientation, + ), + ), ], ); }, diff --git a/pubspec.yaml b/pubspec.yaml index d71439a..b8e3a2e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: wechat_camera_picker description: A camera picker based on WeChat's UI which is a separate runnable extension to wechat_assets_picker. repository: https://github.com/fluttercandies/flutter_wechat_camera_picker -version: 4.0.0-dev.2 +version: 4.0.0-dev.3 environment: sdk: ">=2.18.0 <3.0.0"