Flutter页面切换后ImagePicker失效及组件封装求助
问题解决:图片数据传递与Widget封装
一、解决图片无法在UserProfilePage获取的问题
问题根源
当前代码仅在WorkoutContentPage的本地状态保存了图片文件,既没有上传到云端存储,也未将图片信息写入Firestore的用户文档,导致UserProfilePage无法读取到图片数据。
修改步骤
- 确保集成Firebase Storage依赖(若未添加,在
pubspec.yaml中加入firebase_storage: ^latest_version并执行flutter pub get) - 修改WorkoutContentPage,实现图片上传与数据存储
- 修改UserProfilePage,从Firestore读取图片URL并显示
修改后的WorkoutContentPage关键代码
class WorkoutContentPageState extends State<WorkoutContentPage> { // ... 原有代码保持不变 ... // 添加图片上传到Firebase Storage的方法 Future<String?> uploadImageToStorage(File image) async { try { final storageRef = FirebaseStorage.instance.ref().child('workout_covers/$userId/${DateTime.now().millisecondsSinceEpoch}'); final uploadTask = storageRef.putFile(image); final snapshot = await uploadTask.whenComplete(() {}); return await snapshot.ref.getDownloadURL(); } catch (e) { print('上传图片失败: $e'); return null; } } // 修改底部Continue按钮的点击逻辑 @override Widget build(BuildContext context) { return Scaffold( // ... 原有代码保持不变 ... bottomNavigationBar: BottomAppBar( color: const Color.fromARGB(255, 240, 240, 240), child: Container( width: 50, child: ElevatedButton( onPressed: () async { String? imageUrl; if (image != null) { imageUrl = await uploadImageToStorage(image!); } // 写入Firestore,使用merge避免覆盖其他用户字段 await FirebaseFirestore.instance.collection("Users").doc(userId).set({ "nameprogram": nameprogramController.text, "typeprogram": typeprogramController.text, "typeequipment": typeequipmentController.text, if (imageUrl != null) "coverImageUrl": imageUrl, }, SetOptions(merge: true)); Navigator.push( context, MaterialPageRoute(builder: (context) => UserProfilePage()), ); }, // ... 按钮样式保持不变 ... child: Text( 'Continue', style: TextStyle( fontWeight: FontWeight.bold, color: Colors.white, ), )), ), ), ); } }
修改后的UserProfilePage关键代码
class UserProfilePage extends StatelessWidget { @override Widget build(BuildContext context) { final userId = FirebaseAuth.instance.currentUser!.uid; return Scaffold( appBar: AppBar( title: const Text('User Profile'), ), body: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>( future: FirebaseFirestore.instance.collection("Users").doc(userId).get(), builder: (context, snapshot) { // ... 加载状态、错误处理保持不变 ... final data = snapshot.data!.data()!; final nameprogram = data["nameprogram"]; final typeprogram = data["typeprogram"]; final typeequipment = data["typeequipment"]; final coverImageUrl = data["coverImageUrl"]; // 读取图片URL return Padding( padding: EdgeInsets.only(top: 20, left: 10, right: 10), child: Container( height: 135, width: MediaQuery.of(context).size.width * 0.90, decoration: ShapeDecoration( shape: RoundedRectangleBorder( borderRadius: new BorderRadius.all(new Radius.circular(10))), color: Colors.white, shadows: [ BoxShadow( color: Colors.grey.shade400, blurRadius: 5, spreadRadius: 2, ), ], ), child: Row(mainAxisSize: MainAxisSize.min, children: [ SizedBox(width: 10), // 根据URL显示图片 coverImageUrl != null ? Image.network( coverImageUrl, width: 100, height: 100, fit: BoxFit.cover, ) : Text("No image selected"), const SizedBox(width: 10), // ... 文本内容保持不变 ... ]))); }, ), ); } }
二、封装圆角矩形容器为独立Widget
步骤
创建独立的WorkoutProgramCardWidget,接收所需参数,实现代码复用:
class WorkoutProgramCard extends StatelessWidget { final String nameprogram; final String typeprogram; final String typeequipment; final String? coverImageUrl; const WorkoutProgramCard({ super.key, required this.nameprogram, required this.typeprogram, required this.typeequipment, this.coverImageUrl, }); @override Widget build(BuildContext context) { return Container( height: 135, width: MediaQuery.of(context).size.width * 0.90, decoration: ShapeDecoration( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), color: Colors.white, shadows: [ BoxShadow( color: Colors.grey.shade400, blurRadius: 5, spreadRadius: 2, ), ], ), child: Row(mainAxisSize: MainAxisSize.min, children: [ const SizedBox(width: 10), coverImageUrl != null ? Image.network( coverImageUrl!, width: 100, height: 100, fit: BoxFit.cover, ) : const Text("No image selected"), const SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 25), Text( nameprogram, style: const TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 5), Text( 'type: $typeprogram', style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.grey, ), ), const SizedBox(height: 5), Text( 'equipment: $typeequipment', style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.grey, ), ), ], ), ), ]), ); } }
在UserProfilePage中使用该Widget
class UserProfilePage extends StatelessWidget { @override Widget build(BuildContext context) { final userId = FirebaseAuth.instance.currentUser!.uid; return Scaffold( appBar: AppBar( title: const Text('User Profile'), ), body: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>( future: FirebaseFirestore.instance.collection("Users").doc(userId).get(), builder: (context, snapshot) { // ... 加载状态、错误处理保持不变 ... final data = snapshot.data!.data()!; final nameprogram = data["nameprogram"]; final typeprogram = data["typeprogram"]; final typeequipment = data["typeequipment"]; final coverImageUrl = data["coverImageUrl"]; return Padding( padding: const EdgeInsets.only(top: 20, left: 10, right: 10), child: WorkoutProgramCard( nameprogram: nameprogram, typeprogram: typeprogram, typeequipment: typeequipment, coverImageUrl: coverImageUrl, ), ); }, ), ); } }
内容的提问来源于stack exchange,提问作者sanda17
相关产品推荐
相关产品推荐

