Flutter/如何为动态添加卡片给予独特的照片

68bkxrlz  于 2023-03-24  发布在  Flutter
关注(0)|答案(1)|浏览(107)

我正在用Flutter写一个简单的应用程序,我是这个领域的新手。
我有三个按钮:“开始”、“添加照片”和“完成”。按下“开始”按钮后,“添加照片”和“完成”按钮将变为可见。按下“添加照片”按钮后,将拍摄一张照片并保存为“imageFile”,名称为“my_image. jpg”。然后,此文件将保存到PhotoData。
当我按下完成按钮时,动态卡片会在我的'GecmisPage' dart文件中创建。这些卡片显示来自HistoryData和PhotoData的信息。例如,它存储位置,城市,地区信息和时间。每次按下完成按钮,都会创建一张新卡片,并重复此过程。
我的问题是,我希望使用“添加照片”按钮拍摄的照片显示在卡片中。但是,当我拍摄照片时,相同的照片显示在所有创建的卡片中。将最后拍摄的照片显示在以前创建的卡片中没有意义,是吗?提前感谢任何可以帮助我的人。
代码可能看起来有点复杂。如果你能用这三个按钮用一个小场景来解释它,那也会为我做这项工作。
添加照片按钮:

class Photo {
  String imagePath;
  DateTime dateTaken;

  Photo({
    required this.imagePath,
    required this.dateTaken,
  });
}
class PhotoData{
  static List<Photo> photos = [];

  static void addPhoto(
      String imagePath,
      DateTime dateTaken,
      ) {
    final photoItem = Photo(
      imagePath: imagePath,
      dateTaken: dateTaken,
    );

    photos.add(photoItem);

  }
}


class CameraButton extends StatefulWidget {
  final void Function(File?) onPictureTaken;
  const CameraButton({Key? key, required this.onPictureTaken}) : super(key: key);

  @override
  _CameraButtonState createState() => _CameraButtonState();
}
class _CameraButtonState extends State<CameraButton> {
  
  late File? _image = null;
  final picker = ImagePicker();

  Future getImage() async {
    final pickedFile = await picker.pickImage(source: ImageSource.camera);
    if(pickedFile == null) return;

    setState(() {
      _image = File(pickedFile.path);
    });

    final directory = await getApplicationDocumentsDirectory();
    final imageFile = File('${directory.path}/my_image.jpg');
    await imageFile.writeAsBytes(_image!.readAsBytesSync());

    widget.onPictureTaken(_image!);

  }
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        _image == null
            ? Text('No image selected.')
            : Image.file(_image!),
        ElevatedButton(
          onPressed: getImage,

          child: Text('Take a Picture'),
        ),
      ],
    );
  }
}

GecmisPage:

Container(
                            color: Constant.tema13,
                            child: ListView.builder(
                              itemCount: PhotoData.photos.length,
                              itemBuilder: (BuildContext context, int index) {
                                final photo = PhotoData.photos[index];
                                return ListTile(
                                  leading: Image.file(File(photo.imagePath)),

                                );
                              },
                            ),
                          )

页面支架:

body: ListView.builder(
              itemCount: HistoryData.history.length,
              itemBuilder: (context, index) {
                return Container(
                  width: screenWidth/4,
                  height: screenHeight/10,
                  child: Card(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(15),
                    ),
                    color: Color(0xFFBCF6E7),
                    child: GestureDetector(
                      onTap: () {
                        onCardTap(
                          index,
                          HistoryData.history[index].date as String,
                          HistoryData.history[index].time,
                        );
                      },
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Padding(
                            padding: const EdgeInsets.only(left: 5.0,),
                            child: Image.asset("assets/images/loc.png", height: 30, width: 30,),
                          ),
                          Padding(
                            padding: const EdgeInsets.only(top:20),
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text("Başlangıç Yeri", style: TextStyle(fontSize: 15)),
                                Text("${HistoryData.history[index].city}" + " / " + "${HistoryData.history[index].district}", style: TextStyle(fontSize: 15)),

                              ],
                            ),
                          ),
                          Padding(
                            padding: const EdgeInsets.only(left:30.0),
                            child:
                            Text("${HistoryData.history[index].date}\n${HistoryData.history[index].time}", style: TextStyle(fontSize: 10)),
                          ),
                          Container(
                            margin: EdgeInsets.only(right: 10),
                            child: Checkbox(
                              activeColor: Constant.darkgrey,
                              checkColor: Constant.green,
                              value: _selectedList[index],
                              onChanged: (bool? newValue) {
                                setState(() {
                                  _selectedList[index] = newValue!;
                                });
                              },
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              }),

此外,当在此处单击卡片时,将使用MaterialPageRoute打开一个页面,并使用该页面下面的容器调用照片列表。

Container(
                                color: Constant.opacgrey,
                            child: BlocBuilder<PhotosCubit, PhotosState>(
                              builder: (context, state) {
                                return ListView.builder(
                                  shrinkWrap: true,
                                  itemCount: state.photos.length,
                                  itemBuilder: (BuildContext context, int index) {
                                    final photo = state.photos[index];
                                    return ListTile(
                                      leading: Image.file(File(photo.imagePath)),
                                    );
                                  },
                                );
                              },
                            ),
                          ),

我不完全确定,但我想我可能有问题,因为每次点击卡片时都会打开同一个页面。

4jb9z9bj

4jb9z9bj1#

您需要一些状态管理来轻松处理这个问题,而不是使用PhotoData类中的静态变量和方法;
示例:

class PhotosState extends Equatable {
  const PhotosState({this.photos = const []});

  final List<Photo> photos;

  @override
  List<Object?> get props => [photos];
}

class PhotosCubit extends Cubit<PhotosState> {
  PhotosCubit() : super(const PhotosState());

  void addPhoto(
    String imagePath,
    DateTime dateTaken,
  ) {
    final photo = Photo(imagePath: imagePath, dateTaken: dateTaken);
    emit(
      PhotosState(
        photos: List.of(state.photos)..add(photo),
      ),
    );
  }
}

使用CameraButton时,不要忘记更改onPictureTaken回调

CameraButton(
              onPictureTaken: (file) {
                context
                    .read<PhotosCubit>()
                    .addPhoto(file!.path, DateTime.now());
              },
            ),

最后,您可以使用BlocBuilder来更新您的UI与新添加的Photo

return Container(
      child: BlocBuilder<PhotosCubit, PhotosState>(
        builder: (context, state) {
          return ListView.builder(
            shrinkWrap: true,
            itemCount: state.photos.length,
            itemBuilder: (BuildContext context, int index) {
              final photo = state.photos[index];
              return ListTile(
                leading: Image.file(File(photo.imagePath)),
              );
            },
          );
        },
      ),
    );

相关问题