Почему моя строка флаттера или хранилища изображений не переносится на другую страницу, или наоборот? - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть два файла: ListView, хранящий строки Firestore, и image_picker. Плагины флаттера: cloud_firestore, esys_flutter_share и image_picker

Я хочу, чтобы пользователь приложения (не прошедший проверку подлинности) либо разделял текстовую строку ('title' из базы данных firestore db) ИЛИ прикреплял изображение (из image_picker) - просто поделиться одним или обоими.

Я пытаюсь изучить это, и у меня пока нет github. Вот весь мой код, как я могу получить плагин общего доступа Esys для совместного использования обоих элементов в одной и той же функции _shareImageAndText (), хотя они находятся на отдельных страницах?

Я думал, что функции из класса ImageInput () из image.dart все равно будут работать при импорте на главную страницу (рецепт), но они не работают, я получаю: «_imageFile is undefined» на главной странице или «заголовок» не определен при попытке вызвать его на второй странице. Что я не понимаю? Функции обмена изображениями и текстом работают на соответствующих страницах, но я могу заставить их работать на одной странице одновременно.

    import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'dart:ui';
import 'package:google_fonts/google_fonts.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'dart:async';
import 'image.dart';

class Recipe extends StatefulWidget {
@override
_RecipeState createState() => _RecipeState();
}

 class _RecipeState extends State<Recipe> {
var firestoreDb = Firestore.instance.collection("recipes").snapshots();


   Future<void> _shareText(snapshot, index) async {
try {
  Share.text('Share Text ',
      (snapshot.data.documents[index].data['title']), 'text/plain');
} catch (e) {
  print('error: $e');
}

}

@override
Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(
    title: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Container(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                'Recipes',
                style: GoogleFonts.lato(
                  fontSize: 22.0,
                  color: Colors.amberAccent.shade50,
                ),
              )),
          IconButton(
            icon: Icon(MdiIcons.foodForkDrink, color: Color(0xffffe0b2), size: 32.0),
            onPressed: () {
             null;
            },
          ),
        ]),
    backgroundColor: Colors.lightBlue,
    elevation: 50.0,
  ), //AppBar

  body: Container(
    width: MediaQuery.of(context).size.width,
    child: StreamBuilder(
        stream: firestoreDb,
        builder: (context, snapshot) {
          if (!snapshot.hasData) Text('Loading...');
          return StaggeredGridView.countBuilder(
            crossAxisCount: 2,
            mainAxisSpacing: 1.0,
            crossAxisSpacing: 1.0,
            padding: EdgeInsets.symmetric(horizontal: 2.0, vertical: 6.0),
            shrinkWrap: true,
            itemCount: snapshot.data.documents.length,
            itemBuilder: (context, int index) => Container(
              child: Column(
                children: <Widget>[
                  Card(
                    color: Colors.white,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(12.0),
                    ),

                    child: Column(children: <Widget>[
                      ListTile(
                        title: Text(
                          '${(snapshot.data.documents[index]['title'])}',
                          style: GoogleFonts.lato(
                            fontSize: 20.0,
                            height: 1.2,
                            fontWeight: FontWeight.w500,
                          ),
                          textAlign: TextAlign.center,
                        ),

                        subtitle: Row(
                            mainAxisSize: MainAxisSize.max,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[



                              MaterialButton(         // This shares the Firebase string of text, 'title'   
                                child: Text('Share text'),
                                onPressed: () async => await _shareText(snapshot, index),
                              ),

                              SizedBox(height: 5.0),
                              ImageInput(),  //this displays image called from image_picker to share , it works for sharing an image only.


                              Expanded(
                                child: Text(
                                  '${(snapshot.data.documents[index]['subtitle'])}',
                                  textAlign: TextAlign.right,
                                  style: GoogleFonts.lato(
                                    fontSize: 13.0,
                                    fontWeight: FontWeight.w900,
                                    fontStyle: FontStyle.italic,
                                    color: Colors.blue,
                                  ),
                                ), //subtitle: Text
                              ),
                            ] //children
                        ), //Row
                      ), //listtile
                    ]),
                  ),
                ],
              ),
            ),
            staggeredTileBuilder: (int index) => StaggeredTile.fit(2),
          );
        }),
  ),
 );
} //build
} //class

Это второй страница, которая содержит функцию как изображения, так и текста. Я могу поделиться изображением только из этого метода, строка Firestore (snapshot.data.documents [index] .data ['title']) не будет работать:

    import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/foundation.dart';


  File _imageFile;

  class ImageInput extends StatefulWidget {

  //final String _imageFile;
  //final String title;
  //ImageInput(this._imageFile, this.title);

   @override
  _ImageInputState createState() => _ImageInputState();
  }

 class _ImageInputState extends State<ImageInput> {


 void _getImage(BuildContext context, ImageSource source){
ImagePicker.pickImage(source: source, maxWidth: 500.0, imageQuality: 80).then((File image){
  setState((){
    _imageFile = image;
  });
  Navigator.pop(context);

});
}

void _openImagePicker(BuildContext context) {
 showModalBottomSheet(context: context, builder: (BuildContext context) {
  return Container(
    height: 180.0,
    padding: EdgeInsets.all(10.0),
  child: Column(
    children: [
    Text('Choose photo',
      style:TextStyle(fontWeight: FontWeight.bold),),
      SizedBox(height: 10.0),
      FlatButton(
        textColor: Theme.of(context).primaryColor,
        child: Text('Use Camera'),
      onPressed: () {
          _getImage(context, ImageSource.camera);
      },),
      FlatButton(
        textColor: Theme.of(context).primaryColor,child:
      Text('Open Gallery'),
        onPressed: () {
          _getImage(context, ImageSource.gallery);
        },)

    ]
  ),);
});
}

 Future<void> _shareImageAndText() async {
 try {
  List<int> imageBytes = await _imageFile.readAsBytes();
  var uint8List = Uint8List.fromList(imageBytes);
  await Share.file('esys image', 'esys.jpg', uint8List, 'image/jpeg',
      text: 'My optional text.');
      //text:  (snapshot.data.documents[index].data['title']) );        <======= this does not carry over to main page
} catch (e) {
  print('error: $e');
}
}

@override
Widget build(BuildContext context) {
return Column(
  children: <Widget>[
    OutlineButton(
    onPressed: () {
      _openImagePicker(context);
    },
    child:Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          Icon(Icons.camera_alt, color: Colors.blue.shade700,),
          SizedBox(
            width:1.0,
          ),
          // Text('Add Image'),
        ]
    ),//Row
  ),//outline button

   SizedBox(height: 1.0),
    _imageFile == null ? Text('Add a Pic')  : Image.file(_imageFile,
        fit: BoxFit.cover,
        height: 200.0,
     width: 200.0,
     // width: MediaQuery.of(context).size.width,
      alignment: Alignment.topCenter,
    ),

    MaterialButton(
      child: Text('Send it!'),
      onPressed: () async => await _shareImageAndText(),
    ),
    //pass the snapshot parameter inside your StreamBuilder
    //onPressed: () async => await _shareText(snapshot, index),

  ],
);
}
}

Я пробовал добавлять конструкторы и инициализаторы, но я не достаточно умен, чтобы понять это.

1 Ответ

0 голосов
/ 25 февраля 2020

Сначала добавьте это. добавляется параметр для данных (заголовка), передаваемых во второй класс.

final String title;

ImageInput ({@ required this.yourText});

Я добавил непосредственно в ваш код, как показано ниже.

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/foundation.dart';


  File _imageFile;

  class ImageInput extends StatefulWidget {

  final String title;
  ImageInput({@required this.title});

  //final String _imageFile;
  //final String title;
  //ImageInput(this._imageFile, this.title);

   @override
  _ImageInputState createState() => _ImageInputState();
  }

 class _ImageInputState extends State<ImageInput> {


 void _getImage(BuildContext context, ImageSource source){
ImagePicker.pickImage(source: source, maxWidth: 500.0, imageQuality: 80).then((File image){
  setState((){
    _imageFile = image;
  });
  Navigator.pop(context);

});
}

void _openImagePicker(BuildContext context) {
 showModalBottomSheet(context: context, builder: (BuildContext context) {
  return Container(
    height: 180.0,
    padding: EdgeInsets.all(10.0),
  child: Column(
    children: [
    Text('Choose photo',
      style:TextStyle(fontWeight: FontWeight.bold),),
      SizedBox(height: 10.0),
      FlatButton(
        textColor: Theme.of(context).primaryColor,
        child: Text('Use Camera'),
      onPressed: () {
          _getImage(context, ImageSource.camera);
      },),
      FlatButton(
        textColor: Theme.of(context).primaryColor,child:
      Text('Open Gallery'),
        onPressed: () {
          _getImage(context, ImageSource.gallery);
        },)

    ]
  ),);
});
}

 Future<void> _shareImageAndText() async {
 try {
  List<int> imageBytes = await _imageFile.readAsBytes();
  var uint8List = Uint8List.fromList(imageBytes);
  await Share.file('esys image', 'esys.jpg', uint8List, 'image/jpeg',
      text: widget.title );
      //text:  (snapshot.data.documents[index].data['title']) );        <======= this does not carry over to main page
} catch (e) {
  print('error: $e');
}
}

@override
Widget build(BuildContext context) {
return Column(
  children: <Widget>[
    OutlineButton(
    onPressed: () {
      _openImagePicker(context);
    },
    child:Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          Icon(Icons.camera_alt, color: Colors.blue.shade700,),
          SizedBox(
            width:1.0,
          ),
          // Text('Add Image'),
        ]
    ),//Row
  ),//outline button

   SizedBox(height: 1.0),
    _imageFile == null ? Text('Add a Pic')  : Image.file(_imageFile,
        fit: BoxFit.cover,
        height: 200.0,
     width: 200.0,
     // width: MediaQuery.of(context).size.width,
      alignment: Alignment.topCenter,
    ),

    MaterialButton(
      child: Text('Send it!'),
      onPressed: () async => await _shareImageAndText(),
    ),
    //pass the snapshot parameter inside your StreamBuilder
    //onPressed: () async => await _shareText(snapshot, index),

  ],
);
}
}

Затем вызовите ImageInput следующим образом

ImageInput (title: snapshot.data.documents [index] ['title']),

наконец внутри заголовка доступа класса состояний вашей второй страницы, где бы с помощью

widget.title; // это ваш заголовок, переданный из первого класса

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...