Anonymous
Flutter - мне нужно сделать экран qrcode, где фон должен быть размыт, а центр экрана очищен
Сообщение
Anonymous » 08 июл 2024, 16:20
Мне удалось добавить нужный эффект, но он работает только на устройствах Android, на IOS эффект размытия идет на весь экран.
мой код и печатает:
Страница:
Код: Выделить всё
class HomePayQrcodePage extends StatelessWidget {
const HomePayQrcodePage({required this.controller, super.key});
final HomePayQrcodeController controller;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.transparentWhite,
body: \_body(context),
);
}
Widget \_body(BuildContext context) {
const cutOutSize = 260.0;
const borderRadius = 20.0;
return SafeArea(
child: Stack(
children: [
QRView(
key: GlobalKey(debugLabel: 'HomePayPage'),
onQRViewCreated: controller.onQRViewCreated,
),
Positioned.fill(
child: ClipPath(
clipper: HoleClipper(
cutOutSize: cutOutSize,
borderRadius: borderRadius,
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 6.0, sigmaY: 6.0),
child: Container(
color: Colors.black54.withOpacity(0.3),
),
),
),
),
Positioned(
top: 10,
left: 10,
child: AppBackButton(onTap: controller.onClickBack),
),
],
),
);
}
}
class HoleClipper extends CustomClipper\
{
final double cutOutSize;
final double borderRadius;
HoleClipper({required this.cutOutSize, required this.borderRadius});
@override
Path getClip(Size size) {
final cutOutRect = RRect.fromRectAndRadius(
Rect.fromCenter(
center: Offset(size.width / 2, size.height / 2),
width: cutOutSize,
height: cutOutSize,
),
Radius.circular(borderRadius),
);
final path = Path()
..addRect(Rect.fromLTWH(0, 0, size.width, size.height))
..addRRect(cutOutRect)
..fillType = PathFillType.evenOdd;
return path;
}
@override
bool shouldReclip(CustomClipper\ oldClipper) =\> false;
}
контроллер
Код: Выделить всё
class HomePayQrcodeController extends GetxController {
QRViewController? tQrViewController;
RxInt cardsListIndex = (Get.arguments\[0\] as int).obs;
@override
void dispose() {
super.dispose();
tQrViewController?.dispose();
}
Future\ onQRViewCreated(QRViewController controller) async {
tQrViewController = controller;
controller.scannedDataStream.listen(
(scanData) async {
if (Platform.isAndroid) {
controller.pauseCamera();
} else if (Platform.isIOS) {
controller.resumeCamera();
}
String scanned = scanData.code as String;
log('QR Code Scanned: $scanned');
Get.back(result: scanned);
},
);
}
void onClickBack() {
Get.back(result: 'back');
}
Future\ underConstruction() async {
await Get.toNamed(NamedRoutes.underConstruction);
}
}
Android работает правильно:
введите здесь описание изображения
IOS с проблемой:
введите здесь описание изображения
Поскольку собственный QrScannerOverlayShape QRView не поддерживает эффект размытия, я попытался добавить стек, в котором первая камера является QRView, а вторая — ClipPath, чтобы сделать центральный вырез на экране.
Подробнее здесь:
https://stackoverflow.com/questions/787 ... be-blurred
1720444804
Anonymous
Мне удалось добавить нужный эффект, но он работает только на устройствах Android, на IOS эффект размытия идет на весь экран. мой код и печатает: Страница: [code]class HomePayQrcodePage extends StatelessWidget { const HomePayQrcodePage({required this.controller, super.key}); final HomePayQrcodeController controller; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.transparentWhite, body: \_body(context), ); } Widget \_body(BuildContext context) { const cutOutSize = 260.0; const borderRadius = 20.0; return SafeArea( child: Stack( children: [ QRView( key: GlobalKey(debugLabel: 'HomePayPage'), onQRViewCreated: controller.onQRViewCreated, ), Positioned.fill( child: ClipPath( clipper: HoleClipper( cutOutSize: cutOutSize, borderRadius: borderRadius, ), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 6.0, sigmaY: 6.0), child: Container( color: Colors.black54.withOpacity(0.3), ), ), ), ), Positioned( top: 10, left: 10, child: AppBackButton(onTap: controller.onClickBack), ), ], ), ); } } class HoleClipper extends CustomClipper\ { final double cutOutSize; final double borderRadius; HoleClipper({required this.cutOutSize, required this.borderRadius}); @override Path getClip(Size size) { final cutOutRect = RRect.fromRectAndRadius( Rect.fromCenter( center: Offset(size.width / 2, size.height / 2), width: cutOutSize, height: cutOutSize, ), Radius.circular(borderRadius), ); final path = Path() ..addRect(Rect.fromLTWH(0, 0, size.width, size.height)) ..addRRect(cutOutRect) ..fillType = PathFillType.evenOdd; return path; } @override bool shouldReclip(CustomClipper\ oldClipper) =\> false; } [/code] контроллер [code]class HomePayQrcodeController extends GetxController { QRViewController? tQrViewController; RxInt cardsListIndex = (Get.arguments\[0\] as int).obs; @override void dispose() { super.dispose(); tQrViewController?.dispose(); } Future\ onQRViewCreated(QRViewController controller) async { tQrViewController = controller; controller.scannedDataStream.listen( (scanData) async { if (Platform.isAndroid) { controller.pauseCamera(); } else if (Platform.isIOS) { controller.resumeCamera(); } String scanned = scanData.code as String; log('QR Code Scanned: $scanned'); Get.back(result: scanned); }, ); } void onClickBack() { Get.back(result: 'back'); } Future\ underConstruction() async { await Get.toNamed(NamedRoutes.underConstruction); } } [/code] Android работает правильно: введите здесь описание изображения IOS с проблемой: введите здесь описание изображения Поскольку собственный QrScannerOverlayShape QRView не поддерживает эффект размытия, я попытался добавить стек, в котором первая камера является QRView, а вторая — ClipPath, чтобы сделать центральный вырез на экране. Подробнее здесь: [url]https://stackoverflow.com/questions/78721084/flutter-i-need-to-make-a-qrcode-screen-where-the-background-must-be-blurred[/url]