You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter页面切换后ImagePicker失效及组件封装求助

问题解决:图片数据传递与Widget封装

一、解决图片无法在UserProfilePage获取的问题

问题根源

当前代码仅在WorkoutContentPage的本地状态保存了图片文件,既没有上传到云端存储,也未将图片信息写入Firestore的用户文档,导致UserProfilePage无法读取到图片数据。

修改步骤

  1. 确保集成Firebase Storage依赖(若未添加,在pubspec.yaml中加入firebase_storage: ^latest_version并执行flutter pub get)
  2. 修改WorkoutContentPage,实现图片上传与数据存储
  3. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 16:32:02