I write a code where I have colums in Gridviw and each column has the property to upload the image. The image will be uploaded on that column which is clicked but in my code when I click any column to upload an image it uploads in all columns. so I want to upload an image on a particular column that I click.
so please help me to do this.
here is my code:-
import 'package:flutter/material.dart';
import 'package:mindmatch/utils/widget_functions.dart';
import 'package:mindmatch/custom/BorderIcon.dart';
import 'package:mindmatch/screens/Relation.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import 'dart:io';
class Photos extends StatefulWidget {
var usrid;
Photos({Key? key, @required this.usrid}) : super(key: key);
@override
_Photos createState() => _Photos();
}
class _Photos extends State<Photos>{
PickedFile? _imageFile;
final String uploadUrl = 'https://api.imgur.com/3/upload';
final ImagePicker _picker = ImagePicker();
Future<String?> uploadImage(filepath, url) async {
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(await http.MultipartFile.fromPath('image', filepath));
var res = await request.send();
return res.reasonPhrase;
}
Future<void> retriveLostData() async {
final LostData response = await _picker.getLostData();
if (response.isEmpty) {
return;
}
if (response.file != null) {
setState(() {
_imageFile = response.file;
});
} else {
print('Retrieve error ${response.exception?.code}');
}
}
int counter = 0;
//List<Widget> _list = List<Widget>();
List<Widget> _list = <Widget> [];
@override
void initState() {
for (int i = 0; i < 2; i++) {
Widget child = _newItem(i);
_list.add(child);
};
}
void on_Clicked() {
Widget child = _newItem(counter);
setState(
() => _list.add(child),
);
}
Widget _previewImage(i) {
final _imageFile = this._imageFile;
if (_imageFile != null) {
return
SizedBox(
//width: 300,
height: 100,
child: Center(child:
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.file(
File(
_imageFile.path,
),
height: 80,
)
),
),
);
} else {
return InkWell(
onTap: _pickImage,
child: SizedBox(
//width: 300,
height: 100,
child: Center(child:
Icon(
Icons.image,
color: Color(0xffcccccc),
size: 60,
),
),
),
);
}
}
Widget _newItem(int i) {
Key key = new Key('item_${i}');
Column child = Column(
key: key,
children: [
Stack(
children: [
Card(
elevation: 0,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xffa1a1a1),
),
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: _previewImage(i),
),
Positioned(
top: 9,
right: 9,
child: InkWell(
onTap: () => _removeItem(i),
child: SvgPicture.asset(
width: 20,
'assets/images/close.svg',
height: 20,
),
),
)
]
),
]
);
counter++;
return child;
}
void _removeItem(int i) {
print("====remove $i");
print('===Removing $i');
setState(() => _list.removeAt(i));
}
void _pickImage() async {
try {
final pickedFile = await _picker.getImage(source: ImageSource.gallery);
setState(() {
_imageFile = pickedFile;
});
} catch (e) {
//print("Image picker error ${e!}");
print("Image picker error");
}
}
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
final ThemeData themeData = Theme.of(context);
final double padding = 25;
final sidePadding = EdgeInsets.symmetric(horizontal: padding);
var regID = widget.usrid;
return Theme(
data: ThemeData().copyWith(
dividerColor: Colors.transparent,
backgroundColor: Colors.transparent
),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
leading: Builder(
builder: (BuildContext context) {
return Padding(padding: EdgeInsets.fromLTRB(15, 0, 0, 0),
child: IconButton(
icon: const Icon(
Icons.arrow_back_ios_outlined,
color: Colors.black,
),
onPressed: () { Navigator.pop(context); },
),
);
},
),
),
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
//colors: const [Color.fromRGBO(132,105,211,1), Color.fromRGBO(93,181,233,1), Color.fromRGBO(86,129,233,1)],
colors: [Colors.white, Colors.white]
),
),
width: size.width,
height: size.height,
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
addVerticalSpace(10),
Padding(
padding: sidePadding,
child: const Text(
'Add Your Photos',
style: TextStyle(
color: Colors.black,
fontSize: 20,
),),
),
addVerticalSpace(30),
Expanded(
child: Padding(
padding: sidePadding,
child: Column(
children: [
Expanded(
child: GridView(
//padding: const EdgeInsets.all(8.0),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10.0,
mainAxisSpacing: 15,
//childAspectRatio: 2/1,
),
// children: List.generate(_list.length, (index) {
// //generating tiles with people from list
// return _newItem(index);
// },
// ),
children: List.generate(_list.length + 1,
(index) => index == _list.length ?
InkWell(
onTap: () => on_Clicked(),
child: Column(
children: [
Stack(
children: const [
Card(
elevation: 0,
color: Color(0xff8f9df2),
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xff8f9df2),
),
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: SizedBox(
//width: 300,
height: 100,
child: Center(child:
Icon(
Icons.add,
color: Colors.white,
size: 80.0,
),
),
),
)
]
),
]
),
) :
_newItem(index)),
)
)
],
),
)
),
],
),
],
)
),
),
persistentFooterButtons:[
Padding(
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:[
ElevatedButton.icon( // <-- ElevatedButton
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.arrow_back_ios_outlined,
size: 15.0,
color:Colors.white,
),
label: const Text(
'Back',
style: TextStyle(
fontSize: 20,
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xffFDA766),
minimumSize: const Size(100, 49),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0),)
),
),
Directionality(
textDirection: TextDirection.rtl,
child: ElevatedButton.icon( // <-- ElevatedButton
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Relation(usrid:regID)),
);
},
icon: const Icon(
Icons.arrow_back_ios_outlined,
size: 15.0,
color:Colors.white,
),
label: const Text(
'Next',
style: TextStyle(
fontSize: 20,
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xffFDA766),
minimumSize: const Size(100, 49),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0),)
),
),
),
]
),
),
]
),
);
}
}
And here is my output:- this is the output image before image upload
After image upload:- and this image after upload where it uploads all two columns
Please help me with how I solve this. I pass the argument while uploading but it doesn't work. and it also has functionality of add and remove columns
I need this kind of output:- this is the image of output I want
You are not using
iindex inside_previewImage(i). And when you pick the image, you should store them in a list, something likeList<PickedFile?> _images = [];and inside of setState of_pickImageadd picked image to that list. Now inside of_previewImage(i)you would take only image atiindex from_images.You'll need to set initially null for every new item you add, so you don't get exception 'out of bounds'. So your initState, on_Clicked(), and _previewImage should look like:
Also it would be good if you could refactor your code (for example instead of helper methods use widgets, helper method vs widgets)