Flutter Riverpod 图像未从 UI 中删除

问题描述 投票:0回答:1
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:image_picker/image_picker.dart';

final tryProvider = StateNotifierProvider<TryController, TryState>((ref) {
  return TryController();
});

class Try extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final tryState = ref.watch(tryProvider);
    final tryController = ref.read(tryProvider.notifier);

    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          GestureDetector(
            onTap: () {
              if (tryState.imageFile == null) {
                tryController.pickLogoImage();
              }
            },
            child: Container(
              height: 76,
              width: MediaQuery.of(context).size.width * 0.20,
              decoration: BoxDecoration(
                color: Color(0xffD9D9D9),
                borderRadius: BorderRadius.circular(4),
                image: tryState.imageFile != null
                    ? DecorationImage(
                        image: FileImage(tryState.imageFile!),
                        fit: BoxFit.cover,
                      )
                    : null,
              ),
              child: tryState.imageFile != null
                  ? Stack(
                      children: [
                        Positioned(
                          right: 0,
                          top: 0,
                          child: GestureDetector(
                            onTap: () {
                              tryController.removeLogoImage();
                            },
                            child: Icon(
                              Icons.close,
                              color: Colors.red,
                              size: 20,
                            ),
                          ),
                        ),
                      ],
                    )
                  : Center(
                      child: Text(
                        "Logo",
                        style: Theme.of(context).textTheme.bodyLarge!.copyWith(
                            color: Color(0xff8D8D8D),
                            fontWeight: FontWeight.normal,
                            fontSize: 12),
                      ),
                    ),
            ),
          ),
          GestureDetector(
            onTap: () {
              if (tryState.imageLogo == null) {
                tryController.pickLogo();
              }
            },
            child: Container(
              height: 76,
              width: MediaQuery.of(context).size.width * 0.20,
              decoration: BoxDecoration(
                color: Color(0xffD9D9D9),
                borderRadius: BorderRadius.circular(4),
                image: tryState.imageLogo != null
                    ? DecorationImage(
                        image: FileImage(tryState.imageLogo!),
                        fit: BoxFit.cover,
                      )
                    : null,
              ),
              child: tryState.imageLogo != null
                  ? Stack(
                      children: [
                        Positioned(
                          right: 0,
                          top: 0,
                          child: GestureDetector(
                            onTap: () {
                              tryController.removeLogo();
                            },
                            child: Icon(
                              Icons.close,
                              color: Colors.red,
                              size: 20,
                            ),
                          ),
                        ),
                      ],
                    )
                  : Center(
                      child: Text(
                        "Logo",
                        style: Theme.of(context).textTheme.bodyLarge!.copyWith(
                            color: Color(0xff8D8D8D),
                            fontWeight: FontWeight.normal,
                            fontSize: 12),
                      ),
                    ),
            ),
          ),
        ],
      ),
    );
  }
}

class TryState {
  final File? imageFile;
  final File? imageLogo;

  TryState({this.imageFile, this.imageLogo});

  TryState copyWith({File? imageFile, File? imageLogo}) {
    return TryState(
      imageFile: imageFile ?? this.imageFile,
      imageLogo: imageLogo ?? this.imageLogo,
    );
  }
}

class TryController extends StateNotifier<TryState> {
  TryController() : super(TryState());
  final ImagePicker _picker = ImagePicker();

  void pickLogoImage() async {
    final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      state = state.copyWith(imageFile: File(image.path));
      print("Image picked for imageFile: ${image.path}");
    }
  }

  // To pick imageLogo (second image)
  void pickLogo() async {
    final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      state = state.copyWith(imageLogo: File(image.path));
      print("Image picked for imageLogo: ${image.path}");
    }
  }

  void removeLogoImage() {
    state = state.copyWith(imageFile: null);
    print("Removed imageFile");
  }

  void removeLogo() {
    state = state.copyWith(imageLogo: null);
    print("Removed imageLogo");
  }
}

即使我触发removeLogoImage,图像也不会从UI中删除

当我从图库中将图像添加为文件并稍后将图像设置为 null 时,它不会从 UI 中删除。尽管调用了该函数并且更新了状态,但图像在 UI 中仍然可见。当设置为 null 时,如何确保图像从 UI 中删除?

flutter riverpod
1个回答
0
投票
TryState copyWith({File? imageFile, File? imageLogo}) {
    return TryState(
      imageFile: imageFile ?? this.imageFile,
      imageLogo: imageLogo ?? this.imageLogo,
    );
  }

您获得的州徽标所提供的徽标为空。所以,

void removeLogoImage() {
    state = state.copyWith(imageFile: null);
    print("Removed imageFile");
  }

设置 null 不会有任何结果。它只会设置状态值。

如果

CopyWith
函数中存在空变量,您应该创建并使用
Wrapped
类型。

示例:

创建一个 Wrapped 类来处理 null 值

class Wrapped<T> {
  final T value;
  const Wrapped.value(this.value);
}

更新您的 copyWith 函数以接受 Wrapped 类型值

TryState copyWith({Wrapped<File?>? imageFile, Wrapped<File?>? imageLogo}) {
        return TryState(
          imageFile: imageFile != null ? imageFile.value : this.imageFile,
          imageLogo: imageLogo != null ? imageLogo.value : this.imageLogo,
        );
      }

在 copywith 中设置新值时传递包装值

void removeLogoImage() {
    state = state.copyWith(imageFile:Wrapped.value(null);
    print("Removed imageFile");
  }
© www.soinside.com 2019 - 2024. All rights reserved.