flutter - Image picker - need to convert 'List<XFile>' to 'List<File>?'

497

XFile is a image_picker package's wrapper for the picked file(s). Hence, you obtain a List<XFile> from await ImagePicker().pickMultiImage() call, but try to assign it to a _selectedPostImages field that expects List<File> which produces the type mismatch error.

So, you can either:

  1. Rewrite the _selectedPostImages to expect List<XFile>, like List<XFile>? _selectedPostImages.
  2. Map the _imageList to a list of File, like _selectedPostImages = _imageList.map<File>((xfile) => File(xfile.path)).toList()
Share:
497
rawm
Author by

rawm

I'm learning and trying to make stuff that could help make the world better. Freedom and democracy are the current goals.

Updated on January 03, 2023

Comments

  • rawm
    rawm over 1 year

    I'm using image_picker package to get images and show them in a carousel.

        postNotifier(true).selectedPostImages != null
            ? Container(
                height: 400,
                width: 400,
                child: CarouselSlider.builder(
                    options: CarouselOptions(height: 300),
                    itemCount: selectedImagesList!.length,
                    itemBuilder: (BuildContext context, index, realIndex) {
                      final selectedImage = selectedImagesList[index];
                      return buildImage(selectedImage, index);
                    }),
              )
            : const SizedBox(
                height: 0,
              ),
    

    and I'm getting the images for carousel builder from this buildImage() widget

      Widget buildImage(File selectedImage, int index) => Container(
            margin: EdgeInsets.symmetric(horizontal: 12),
            color: Colors.grey,
            child: Image.file(selectedImage),
          );
    

    my PostNotifier class in another file

    class PostNotifier extends ChangeNotifier {
    
      List<File>? _selectedPostImages;
      List<File>? get selectedPostImages => _selectedPostImages;
    
      Future<List?> pickPostImages() async {
        final _imageList = await ImagePicker().pickMultiImage(imageQuality: 5);
        if (_imageList != null) {
          _selectedPostImages = _imageList; //I'm getting the error here.
          notifyListeners();
        }
      }
    

    The error flutter shows is:

    A value of type 'List' can't be assigned to a variable of type 'List?'. Try changing the type of the variable, or casting the right-hand type to 'List?'.

    I tried using flutter_absolute_path as suggested in other answers in such a situation to get the path and set it to the array but when I run on emulator I get this error

    The plugin `flutter_absolute_path` uses a deprecated version of the Android embedding.
    To avoid unexpected runtime failures, or future build failures, try to see if this plugin supports the Android V2 embedding. Otherwise, consider removing it since a future release of Flutter will remove these deprecated APIs.
    If you are plugin author, take a look at the docs for migrating the plugin to the V2 embedding: https://flutter.dev/go/android-plugin-migration.
    Launching lib\main.dart on Android SDK built for x86 in debug mode...
    lib\main.dart:1
    /C:/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_absolute_path-1.0.6/lib/flutter_absolute_path.dart:11:23: Error: Null safety features are disabled for this library.
    Try removing the package language version or setting the language version to 2.12 or higher.
      static Future<String?> getAbsolutePath(String uri) async {
                          ^
    Error: Cannot run with sound null safety, because the following dependencies
    don't support null safety:
    
     - package:flutter_absolute_path
    
    For solutions, see https://dart.dev/go/unsound-null-safety
    : Error: The argument type 'String?' can't be assigned to the parameter type 'String' because 'String?' is nullable and 'String' isn't.
    lib/…/notifier/post.notifier.dart:101
            File tempFile = File(filePath);
                                 ^
    /C:/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_absolute_path-1.0.6/lib/flutter_absolute_path.dart:15:17: Error: Null safety features are disabled for this library.
    Try removing the package language version or setting the language version to 2.12 or higher.
        final String? path = await _channel.invokeMethod('getAbsolutePath', params);
                    ^
    2
    
    FAILURE: Build failed with an exception.
    
    * Where:
    Script 'C:\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 1102
    
    * What went wrong:
    Execution failed for task ':app:compileFlutterBuildDebug'.
    > Process 'command 'C:\flutter\bin\flutter.bat'' finished with non-zero exit value 1
    
    * Try:
    > Run with --stacktrace option to get the stack trace.
    > Run with --info or --debug option to get more log output.
    > Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 1m 48s
    Exception: Gradle task assembleDebug failed with exit code 1
    Exited (sigterm)
    

    and the app never opens on emualtor.

    What do I do? I want to implement this multi image picker.

    • rawm
      rawm about 2 years
      Oops, I didn't notice that the blockquote removed content between <>. My error is: A value of type 'List<XFile>' can't be assigned to a variable of type 'List<File>?'. Try changing the type of the variable, or casting the right-hand type to 'List<File>?'
    • ישו אוהב אותך
      ישו אוהב אותך about 2 years
      either change List<File>? to List<XFile>? or convert it to File: _selectedPostImages = _imageList.map((el) => File(el.path)).toList();
  • rawm
    rawm about 2 years
    Thanks for the solution. This works but whenever i go to reselect images the list is built again. How to make it so that new images get added to the already populated list?
  • Marcin Wróblewski
    Marcin Wróblewski about 2 years
    What you ask for have a potential to be standalone question 😀 Please create one, link it here, and I’ll try to answer.