在允许在手机后置摄像头和地图之间切换的 Flutter 屏幕上工作时,这两个元素都能正确加载。但是,当尝试通过点击按钮在它们之间切换时,会发生错误,导致应用程序崩溃。错误信息是:
F/颤动(5152): [致命:flutter/shell/platform/android/surface_texture_external_texture.cc(56)] 检查失败:state_ == AttachmentState::kAttached。 F / libc(5152): 致命信号 6 (SIGABRT),tid 5152 中的代码 -1 (SI_QUEUE) (充足的切换),pid 5152(充足的切换)。
这是我当前的屏幕代码:
class CameraScreen extends StatefulWidget {
@override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State<CameraScreen> with WidgetsBindingObserver {
late CameraController camera_controller;
bool camera_preview_major = true;
bool is_currposition_available = false;
Position? currPosition;
Map<MarkerId, Marker> markers = <MarkerId, Marker>{};
Completer<GoogleMapController> _controller = Completer();
late GoogleMapController mapsController;
@override
void initState() {
super.initState();
initCameraController();
getCurrentPosition();
requestLocationPermission();
}
@override
void dispose() {
// Dispose of the camera controller
camera_controller.dispose();
// Dispose of GoogleMapController if applicable
// _controller.future.then((mapController) {
// mapController.dispose();
// });
super.dispose();
}
void toggleCameraPreview() {
if (camera_preview_major) {
// When switching to camera view, reinitialize the camera
initCameraController();
} else {
// When switching away from camera view, dispose of the camera controller to free up resources
camera_controller .dispose();
}
setState(() {
camera_preview_major = !camera_preview_major;
});
}
Future<void> requestLocationPermission() async {
var status = await Permission.location.status;
if (!status.isGranted) {
await Permission.location.request();
}
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
body: Column(
children: [
Expanded(
child: Stack(
children: [
// The camera preview is shown in full screen by default
camera_preview_major ? getCameraPreview(camera_controller, size) : getMaps(),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkWell(
onTap: () {
setState(() {
camera_preview_major = !camera_preview_major; // Toggle the view
});
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(color: Colors.black.withOpacity(0.14), blurRadius: 4, spreadRadius: 1),
],
borderRadius: BorderRadius.circular(100),
),
child: Row(
children: [
Icon(
camera_preview_major ? Icons.location_on : Icons.camera_alt_rounded,
color: Colors.blueAccent,
size: 20,
),
SizedBox(width: 5),
Text(camera_preview_major ? "Maps View" : "Camera View"),
],
),
),
Expanded(child: Container()),
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 2, vertical: 2),
width: size.width / 3,
height: size.width / 3,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(color: Colors.black.withOpacity(0.14), blurRadius: 4, spreadRadius: 1),
],
borderRadius: BorderRadius.circular(4),
),
// The maps are shown in the small box by default
child: camera_preview_major ? getMaps() : getCameraPreview(camera_controller, size),
),
),
],
),
),
),
],
)
],
),
),
],
),
);
}
getCameraPreview(CameraController controller, Size size) {
if (!controller.value.isInitialized&&camera_controller != null) {
return const SizedBox(
height: 2,
width: 2,
child: LinearProgressIndicator(
color: Colors.grey,
));
}
return SizedBox(width: size.width, child: CameraPreview(controller));
}
initCameraController() {
camera_controller = CameraController(
config.cameras[0], ResolutionPreset.low,
enableAudio: false);
camera_controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
}).catchError((Object e) {
if (e is CameraException) {
switch (e.code) {
case 'CameraAccessDenied':
break;
default:
print('Handle other errors.');
break;
}
}
});
camera_controller.addListener(() async {
// camera_controller.value.isRecordingPaused
});
}
getMaps() {
return is_currposition_available
? GoogleMap(
zoomControlsEnabled: false,
myLocationEnabled: true,
myLocationButtonEnabled: true,
compassEnabled: true,
initialCameraPosition: CameraPosition(
target: LatLng(currPosition?.latitude ?? 0.0,
currPosition?.longitude ?? 0.0),
zoom: config.mapsInitialZoom,
),
markers: Set<Marker>.of(markers.values),
onMapCreated: (GoogleMapController controller) {
if (!_controller.isCompleted) {
_controller.complete(controller);
mapsController = controller;
}
},
)
: Center(child: CircularProgressIndicator());
}
getCurrentPosition() {
Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.best)
.then((pos) {
setState(() {
currPosition = pos;
is_currposition_available = true;
});
}).catchError((e) {
print("Error getting location: $e");
// Handle the error by showing an alert dialog or a snackbar
// or by setting a flag to show a message in the UI
});
}
}
我可以在稳定版 3.16.9 上重现此问题,但它似乎已在 3.19.0 上修复