flutter - 如何根据动态变化隐藏或显示在 FutureBuilder 中构建的小部件
问题描述
我能够显示和隐藏我想要的小部件,但它每次都会闪烁或重建它自己。我只想在指南针度数达到 190 度时显示捕获图标按钮
这是我的主要小部件
late List<CameraDescription> cameras;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: CameraApp(),
);
}
}
class CameraApp extends StatefulWidget {
@override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
String? imagePath;
XFile? imageFile;
late CameraController controller;
late Future<void> _initializeControllerFuture;
int? angleResult;
bool showCaptureButton = false;
String? getLocation;
bool k = false;
void getAngleFromCompass(newResult) {
WidgetsBinding.instance!.addPostFrameCallback((_) {
setState(() {
angleResult = newResult;
});
});
}
void getLocationRes(newResult) {
getLocation = newResult;
}
@override
void initState() {
super.initState();
controller = CameraController(
// Get a specific camera from the list of available cameras.
cameras[0],
// Define the resolution to use.
ResolutionPreset.high,
imageFormatGroup: ImageFormatGroup.yuv420,
);
_initializeControllerFuture = controller.initialize().then((value) {
setState(() {});
});
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
void _captureImage() async {
await takePicture().then((filePath) {
if (mounted) {
setState(() {
imagePath = filePath;
});
}
});
}
Widget cameraWidget(context) {
var camera = controller.value;
final size = MediaQuery.of(context).size;
var scale = size.aspectRatio * camera.aspectRatio;
if (scale < 1) scale = 1 / scale;
return Transform.scale(
scale: scale,
child: Center(
child: CameraPreview(controller),
),
);
}
@override
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return Container();
}
theCompassApp(getAngleFromCompass) 在这里一直闪烁
return Scaffold(
body: FutureBuilder(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Stack(
children: [
cameraWidget(context),
Align(
alignment: Alignment.topCenter,
child: LocationApp(getLocationRes),
),
Align(
child: CompassApp(getAngleFromCompass),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
color: Color(0xAA333639),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
angleResult == 190 ? IconButton(
onPressed: () => _captureImage(),
iconSize: 40,
icon: Icon(
Icons.camera_alt,
color: Colors.white,
),
) : Text(''),
],
),
),
)
],
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
指南针应用小部件
class CompassApp extends StatefulWidget {
final getAngleValue;
CompassApp(this.getAngleValue);
@override
_CompassAppState createState() => _CompassAppState();
}
class _CompassAppState extends State<CompassApp> {
bool _hasPermissions = false;
@override
void initState() {
super.initState();
_fetchPermissionStatus();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.transparent,
body: Builder(builder: (context) {
if (_hasPermissions) {
return Column(
children: <Widget>[
Expanded(child: _buildCompass()),
],
);
} else {
return Text('');
}
}),
),
);
}
Widget _buildCompass() {
return StreamBuilder<CompassEvent>(
stream: FlutterCompass.events,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 30),
child: Text('Error reading heading not support'),
);
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
double? direction = snapshot.data!.heading;
int ang = direction!.round();
指南针角度在此处传递给主小部件
widget.getAngleValue(ang);
if (direction.isNaN)
return Center(
child: Text("Device does not have sensors !"),
);
return Material(
color: Colors.transparent,
child: Column(
children: [
RotatedBox(
quarterTurns: 1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 41),
child: Text(
'$ang',
style: TextStyle(
fontSize: 50,
color: Colors.white,
backgroundColor: Colors.black26),
),
),
),
],
),
);
},
);
}
void _fetchPermissionStatus() {
Permission.locationWhenInUse.status.then((status) {
if (mounted) {
setState(() => _hasPermissions = status == PermissionStatus.granted);
}
});
}
}
解决方案
你试过了吗Visibility
?Opacity
能见度
Visibility(
visible: true, //false for invisible
child: Text('I am visible'),
),
不透明度
Opacity(
opacity: 1.0, //0.0 for invisible
child: Text('I am visible'),
),
推荐阅读
- arrays - 如何在 JS ES6 中使用解构语法动态创建解包变量名?
- c++ - x * 0.1 和 x / 10 之间的差异?
- python-3.x - 如何将方法添加到类模板视图
- laravel - laravel 中的 laravelcollective 选择选项
- reactjs - 在 React.js 中监听 contenteditable 的变化
- java - IntelliJ 未检测到设备
- javascript - vanilla js - classList.add 不工作,但 className 工作?
- sql - 将数组查询到数据库中并与 ID SQL Typescript 进行比较
- mysql - 连接两个表并使用计算列
- r - 基于A列在R中组合多行