Как правильно отобразить сделанную фотографию?

#flutter #dart #flutter-dependencies

#flutter #dart #flutter-зависимости

Вопрос:

У меня есть пользовательское приложение, в котором я использую диалоги для опроса пользователей, чтобы сохранить места. Когда я делаю снимок, файл сохраняется на устройстве, но не отображается. Где у меня ошибка в моем коде, когда я пытался отобразить изображение?

Код:

 import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart' as syspaths;

class PlacesListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return _Map();
  }
}

class _Map extends StatefulWidget {
  @override
  _MapState createState() => _MapState();
}

class _MapState extends State<_Map> {
  File _storedImage;

  final picker = ImagePicker();
  final _titleController = TextEditingController();

  Future _takeImage() async {
    final pickedFile = await picker.getImage(
      source: ImageSource.camera,
      maxWidth: 600,
    );

    if (pickedFile == null) {
      return;
    }

    _storedImage = File(pickedFile.path);

    final appDir = await syspaths.getApplicationDocumentsDirectory();
    final fileName = path.basename(_storedImage.path);
    await _storedImage.copy('${appDir.path}/$fileName');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Locations'),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.add),
            onPressed: () {
              return showDialog(
                context: context,
                builder: (ctx) => AlertDialog(
                  title: Text(
                    "Do you want add current place to the map?",
                    textAlign: TextAlign.center,
                  ),
                  content: TextField(
                    decoration: InputDecoration(labelText: 'Place title'),
                    controller: _titleController,
                  ),
                  actions: <Widget>[
                    FlatButton(
                      onPressed: () {
                        Navigator.of(ctx).pop();
                      },
                      child: Text("No"),
                    ),
                    FlatButton(
                      onPressed: () {
                        return showDialog(
                          context: context,
                          builder: (ctx) => AlertDialog(
                            title: Text(
                              "Do you want take photo of current place?",
                              textAlign: TextAlign.center,
                            ),
                            content: Container(
                              width: 150,
                              height: 100,
                              decoration: BoxDecoration(
                                border:
                                    Border.all(width: 1, color: Colors.grey),
                              ),
                              child: _storedImage != null
                                  ? Image.file(
                                      _storedImage,
                                      fit: BoxFit.cover,
                                      width: double.infinity,
                                    )
                                  : Text('No photo taken yet',
                                      textAlign: TextAlign.center),
                              alignment: Alignment.center,
                            ),
                            actions: <Widget>[
                              FlatButton(
                                onPressed: () {
                                  Navigator.of(ctx).pop();
                                },
                                child: Text("No"),
                              ),
                              FlatButton(
                                onPressed: _takeImage,
                                child: Text("Yes"),
                              ),
                            ],
                          ),
                        );
                      },
                      child: Text("Yes"),
                    ),
                  ],
                ),
              );
              // Navigator.of(context).pushNamed(AddPlaceScreen.routeName);
            },
          ),
        ],
      ),
      body: Text("Application Content")
    );
  }
}
 

Здесь фотография не отображается:

 Image.file(
    _storedImage,
    fit: BoxFit.cover,
    width: double.infinity,
)
 

Может быть, у меня ошибка в состояниях или в другой части моего кода?

Комментарии:

1. Я пробовал, и это возвращаемый тип файла. Вот пример File: '/storage/emulated/0/Android/data/com.example.newapp/files/Pictures/scaled_b620eb3d-8593-4c86-9f5c-86f0c5b140806435648232718571362.jpg' @Uni

2. Но когда сделана фотография, мой виджет не перестроен, и изображение не отображается @Uni

Ответ №1:

Вы можете скопировать вставить запустить полный код ниже
Вы можете использовать StatefulBuilder , передавать StateSetter _takeImage и вызывать setState
фрагмент кода

 Future _takeImage(StateSetter setState) async {
    ...
    setState(() {
      _storedImage = File(pickedFile.path);
    });

...
return showDialog(
            context: context,
            builder: (ctx) => StatefulBuilder(builder:
                    (BuildContext context,
                        StateSetter setState) { 
...
FlatButton(
                onPressed: () =>
                    _takeImage(setState),
                child: Text("Yes"),
              ),    
 

рабочая демонстрация

введите описание изображения здесь

полный код

 import 'package:flutter/material.dart';
import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart' as syspaths;

class PlacesListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return _Map();
  }
}

class _Map extends StatefulWidget {
  @override
  _MapState createState() => _MapState();
}

class _MapState extends State<_Map> {
  File _storedImage;

  final picker = ImagePicker();
  final _titleController = TextEditingController();

  Future _takeImage(StateSetter setState) async {
    final pickedFile = await picker.getImage(
      source: ImageSource.camera,
      maxWidth: 600,
    );

    if (pickedFile == null) {
      return;
    }

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

    final appDir = await syspaths.getApplicationDocumentsDirectory();
    final fileName = path.basename(_storedImage.path);
    await _storedImage.copy('${appDir.path}/$fileName');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Locations'),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.add),
              onPressed: () {
                return showDialog(
                    context: context,
                    builder: (ctx) => AlertDialog(
                          title: Text(
                            "Do you want add current place to the map?",
                            textAlign: TextAlign.center,
                          ),
                          content: TextField(
                            decoration:
                                InputDecoration(labelText: 'Place title'),
                            controller: _titleController,
                          ),
                          actions: <Widget>[
                            FlatButton(
                              onPressed: () {
                                Navigator.of(ctx).pop();
                              },
                              child: Text("No"),
                            ),
                            FlatButton(
                              onPressed: () {
                                return showDialog(
                                    context: context,
                                    builder: (ctx) => StatefulBuilder(builder:
                                            (BuildContext context,
                                                StateSetter setState) {
                                          return AlertDialog(
                                            title: Text(
                                              "Do you want take photo of current place?",
                                              textAlign: TextAlign.center,
                                            ),
                                            content: Container(
                                              width: 150,
                                              height: 100,
                                              decoration: BoxDecoration(
                                                border: Border.all(
                                                    width: 1,
                                                    color: Colors.grey),
                                              ),
                                              child: _storedImage != null
                                                  ? Image.file(
                                                      _storedImage,
                                                      fit: BoxFit.cover,
                                                      width: double.infinity,
                                                    )
                                                  : Text('No photo taken yet',
                                                      textAlign:
                                                          TextAlign.center),
                                              alignment: Alignment.center,
                                            ),
                                            actions: <Widget>[
                                              FlatButton(
                                                onPressed: () {
                                                  Navigator.of(ctx).pop();
                                                },
                                                child: Text("No"),
                                              ),
                                              FlatButton(
                                                onPressed: () =>
                                                    _takeImage(setState),
                                                child: Text("Yes"),
                                              ),
                                            ],
                                          );
                                        }));
                              },
                              child: Text("Yes"),
                            ),
                          ],
                        ));
                // Navigator.of(context).pushNamed(AddPlaceScreen.routeName);
              },
            ),
          ],
        ),
        body: Text("Application Content"));
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: PlacesListScreen(),
    );
  }
}