У меня есть два файла: 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),
],
);
}
}
Я пробовал добавлять конструкторы и инициализаторы, но я не достаточно умен, чтобы понять это.