large image when clicking - flutter - flutter

I have an algorithm working, and I need to click on the image to show it on the entire screen, I have not succeeded, I send all the code, add a comment "// THIS IS THE IMAGE I NEED TO LOOK BIG WHEN I CLICK" which is the image that I want to make it look large when I click it, I have tried in several ways but I have not been able to solve it, and the only thing I am missing is this functionality.
import 'dart:async';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:tienda/models/productos_model.dart';
import 'package:tienda/pages/otra_pagina.dart';
import 'package:tienda/pages/crear_productos.dart';
import 'package:tienda/pages/pedido_lista.dart';
import 'package:tienda/services/firebase_services.dart';
import 'package:tienda/widgets/header.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
//title: 'Flutter Demo',
theme: ThemeData(
//primarySwatch: Colors.yellow,
primaryColor: Colors.yellow[800],
),
home: MyHomePage(title: 'RETO SAN JOSE CHAPARRAL'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<ProductosModel> _productosModel = List<ProductosModel>();
List<ProductosModel> _listaCarro = [];
FirebaseService db = new FirebaseService();
StreamSubscription<QuerySnapshot> productSub;
#override
void initState() {
super.initState();
_productosModel = new List();
productSub?.cancel();
productSub = db.getProductList().listen((QuerySnapshot snapshot) {
final List<ProductosModel> products = snapshot.documents
.map((documentSnapshot) =>
ProductosModel.fromMap(documentSnapshot.data))
.toList();
setState(() {
this._productosModel = products;
});
});
}
#override
void dispose() {
productSub?.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 16.0, top: 8.0),
child: GestureDetector(
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Icon(
Icons.shopping_cart,
size: 38,
),
if (_listaCarro.length > 0)
Padding(
padding: const EdgeInsets.only(left: 2.0),
child: CircleAvatar(
radius: 8.0,
backgroundColor: Colors.red,
foregroundColor: Colors.white,
child: Text(
_listaCarro.length.toString(),
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 12.0),
),
),
),
],
),
onTap: () {
if (_listaCarro.isNotEmpty)
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Cart(_listaCarro),
),
);
},
),
)
],
),
drawer: Container(
width: 170.0,
child: Drawer(
child: Container(
width: MediaQuery.of(context).size.width * 0.5,
//color: Colors.black, //color de menu principal
color: Colors.yellow[800],
child: new ListView(
padding: EdgeInsets.only(top: 30.0),
children: <Widget>[
Container(
height: 120,
child: new UserAccountsDrawerHeader(
accountName: new Text(''),
accountEmail: new Text(''),
decoration: new BoxDecoration(
image: new DecorationImage(
fit: BoxFit.fill,
image: AssetImage('assets/images/food1x.png'),
),
),
),
),
new Divider(),
new ListTile(
title: new Text(
'productos',
style: TextStyle(color: Colors.white),
),
trailing: new Icon(
Icons.fastfood,
size: 30.0,
color: Colors.white,
),
onTap: () =>
Navigator.of(context).push(new MaterialPageRoute(
builder: (BuildContext context) => CrearProductos(),
)),
),
new Divider(),
],
),
),
),
),
body: SafeArea(
child: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
WaveClip(),
Container(
color: Colors.transparent,
padding: const EdgeInsets.only(left: 24, top: 48),
height: 170,
child: ListView.builder(
itemCount: _productosModel.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Row(
children: <Widget>[
Container(
height: 300,
padding: new EdgeInsets.only(
left: 10.0, bottom: 10.0),
child: Card(
elevation: 7.0,
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(24)),
child: AspectRatio(
aspectRatio: 1,
child: CachedNetworkImage(
imageUrl:
'${_productosModel[index].image}' +
'?alt=media',
fit: BoxFit.cover,
placeholder: (_, __) {
return Center(
child:
CupertinoActivityIndicator(
radius: 15,
));
}),
),
),
),
],
);
},
))
],
),
Container(height: 3.0, color: Colors.grey),
SizedBox(
height: 5.0,
),
Container(
color: Colors.grey[300],
height: MediaQuery.of(context).size.height / 1.5,
child: GridView.builder(
padding: const EdgeInsets.all(4.0),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: _productosModel.length,
itemBuilder: (context, index) {
final String imagen = _productosModel[index].image;
var item = _productosModel[index];
return Card(
elevation: 4.0,
child: Stack(
fit: StackFit.loose,
alignment: Alignment.center,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: CachedNetworkImage(
// THIS IS THE IMAGE I NEED TO LOOK BIG WHEN I CLICK
imageUrl:
'${_productosModel[index].image}' +
'?alt=media',
fit: BoxFit.cover,
placeholder: (_, __) {
return Center(
child:
CupertinoActivityIndicator(
radius: 15,
));
}),
),
Text(
'${_productosModel[index].name}',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
SizedBox(
height: 15,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
height: 25,
),
Text(
'${_productosModel[index].price.toString()}COP',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
color: Colors.black),
),
Padding(
padding: const EdgeInsets.only(
right: 8.0,
bottom: 8.0,
),
child: Align(
alignment: Alignment.bottomRight,
child: GestureDetector(
child: (!_listaCarro
.contains(item))
? Icon(
Icons.shopping_cart,
color: Colors.yellow[800],
size: 38,
)
: Icon(
Icons.shopping_cart,
color: Colors.red,
size: 38,
),
onTap: () {
setState(() {
if (!_listaCarro
.contains(item))
_listaCarro.add(item);
else
_listaCarro.remove(item);
});
},
),
),
),
],
)
],
),
],
));
},
)),
],
),
)),
));
}
}

Another solution is to show the larger image on the same screen using the dialog below.
InkWell(
onTap: () => showDialog(
builder: (BuildContext context) => AlertDialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.all(2),
title: Container(
decoration: BoxDecoration(),
width: MediaQuery.of(context).size.width,
child: Expanded(
child: Image.network(
'${_productosModel[index].image}' +
'?alt=media',
fit: BoxFit.fitWidth,
),
),
),
),
context: context),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
BaseUrl.host + posts!.imageUrl!,
fit: BoxFit.cover,
),
),
)

You can create a new page, wrap the image widget in a InkWell widget, and when tapped navigate to the new page showing the image.
EDIT:
Your widget image would become:
// THIS IS THE IMAGE I NEED TO LOOK BIG WHEN I CLICK
return InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => ImageScreen(
url: '${_productosModel[index].image}' + '?alt=media',
),
),
),
child: Expanded(
child: CachedNetworkImage(
imageUrl: '${_productosModel[index].image}' + '?alt=media',
fit: BoxFit.cover,
placeholder: (_, __) {
return Center(
child: CupertinoActivityIndicator(
radius: 15,
),
);
},
),
),
),
And then you create a new stateless widget which it builds a:
import 'package:flutter/material.dart';
class ImageScreen extends StatelessWidget {
final String? url;
ImageScreen({
Key? key,
#required this.url,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Expanded(
child: CachedNetworkImage(
imageUrl: '${this.url}',
// Ajust the image changing the box fit attributte
fit: BoxFit.cover,
placeholder: (_, __) {
return Center(
child: CupertinoActivityIndicator(
radius: 15,
),
);
},
),
),
);
}
}
After that when you click the app navigates to a new screen rendering only the image. You can add a back button later.

Related

i need too array prouducts from higher to lower id (products on firebase)

class WildWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Obx(()=>GridView.count(
crossAxisCount: 3,
childAspectRatio: .48,
padding: const EdgeInsets.all(15),
mainAxisSpacing: 4.0,
crossAxisSpacing: 10,
children: productController.wild.map((ProductModel product) {
return SingleProductWidget(product: product,);
}).toList())
);
}
}
class SingleProductWidget extends StatelessWidget {
final ProductModel product;
const SingleProductWidget({Key key, this.product}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5)),
child:
Column(
children: [
GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (_) =>Material(
type: MaterialType.transparency,
child: Center(
child:
Padding(
padding:
EdgeInsets.symmetric(vertical:(60)),
child:
CachedNetworkImage(
imageUrl: product.image,
fit: BoxFit.fill,
placeholder: (context, url) => new SpinKitWave(color: Color.fromARGB(255, 0, 53, 145), size: 30,),
errorWidget: (context, url, error) => new Icon(Icons.error),// Fixes border issues
height: double.infinity,
width: double.infinity,
),
),
),
),
);
}, // Image tapped
child:
CachedNetworkImage(
//height: 220,
//width: 140,
imageUrl: product.image,
placeholder: (context, url) => new SpinKitWave(color: Color.fromARGB(255, 0, 53, 145), size: 30,),
errorWidget: (context, url, error) => new Icon(Icons.error),
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal:(0)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: CustomText(
text: "\$${product.price}",
size: 11,
weight: FontWeight.bold,),),
Expanded(
child:SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: CustomText(
text: product.id,
color: kPrimaryColor,
size: 14,
weight: FontWeight.bold,
),
)
),
IconButton(
icon: Icon(Icons.add_shopping_cart),
onPressed: () {
cartController.addProductToCart(product);
})
],
),
),
],
),
);
}
}
this is products , its shown from lower to higher

Scrollable Column and ListView.builder

I want to have a Column and ListView.builder to be scrollable using the SingleChildScrollView. I tried wrapping both the Column or the SingleChildScrollView with Expanded but I'm still not winning. I just want the ListView.builder and the Container above it to be scrollable. Please help...
I am getting an error that says : RenderFlex children have non-zero flex but incoming height constraints are unbounded.
import 'package:flutter/material.dart';
import 'package:ionicons/ionicons.dart';
import 'package:provider/provider.dart';
import '../widgets/product_item.dart';
import '../providers/products.dart';
class ProductsOverviewScreen extends StatelessWidget {
const ProductsOverviewScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final productsData = Provider.of<Products>(context);
final products = productsData.items;
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () {},
icon: const Icon(
Ionicons.notifications_outline,
),
),
title: SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.1,
child: Image.asset(
'assets/logo.png',
fit: BoxFit.contain,
),
),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(
Ionicons.cart_outline,
),
),
],
),
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
height: 140,
width: MediaQuery.of(context).size.width * 0.9,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(26.0),
color: Colors.grey[300],
),
),
Row(
children: const [
Padding(
padding: EdgeInsets.only(
left: 15.0,
top: 20.0,
),
child: Text(
'Place Order',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
],
),
Expanded(
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: products.length,
itemBuilder: (ctx, i) => ProductItem(
products[i].id,
products[i].name,
products[i].size,
products[i].price,
products[i].image,
),
),
)
],
),
),
);
}
}
// The solution to your problem is to make the Listview non using enter code here scrollable and set shrinkwrap to true. Then wrap the first column in SingleChildScrollView. You don't need Expanded or Flexible Widget for this approach.
import 'package:flutter/material.dart';
class ProductsOverviewScreen extends StatelessWidget {
const ProductsOverviewScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final productsData = Provider.of<Products>(context);
final products = productsData.items;
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () {},
icon: const Icon(
Icons.info_outline,
),
),
title: SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.1,
child: Image.asset(
'assets/logo.png',
fit: BoxFit.contain,
),
),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(
Icons.shopping_cart_outlined,
),
),
],
),
body: SingleChildScrollView(
child: Column(
// mainAxisSize: MainAxisSize.min,
children: [
Container(
height: 140,
width: MediaQuery.of(context).size.width * 0.9,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(26.0),
color: Colors.grey[300],
),
),
Row(
children: const [
Padding(
padding: EdgeInsets.only(
left: 15.0,
top: 20.0,
),
child: Text(
'Place Order',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
],
),
ListView.builder(
shrinkWrap: true,
itemCount: 10,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (ctx, i) => ProductItem(
products[i].id,
products[i].name,
products[i].size,
products[i].price,
products[i].image,
),
)
],
),
),
);
}
}
This is one approach among thousands of solutions, it consists of nesting one listview inside another. If you wish you can make the listview.builder horizontal.
import 'package:flutter/material.dart';
import 'package:ionicons/ionicons.dart';
import 'package:provider/provider.dart';
import '../widgets/product_item.dart';
import '../providers/products.dart';
class ProductsOverviewScreen extends StatelessWidget {
const ProductsOverviewScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final productsData = Provider.of<Products>(context);
final products = productsData.items;
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () {},
icon: const Icon(
Ionicons.notifications_outline,
),
),
title: SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
height: MediaQuery.of(context).size.height * 0.1,
child: Image.asset(
'assets/logo.png',
fit: BoxFit.contain,
),
),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(
Ionicons.cart_outline,
),
),
],
),
body: ListView(
scrollDirection: Axis.vertical,
children: [
Container(
height: 140,
width: MediaQuery.of(context).size.width * 0.9,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(26.0),
color: Colors.grey[300],
),
),
Row(
children: const [
Padding(
padding: EdgeInsets.only(
left: 15.0,
top: 20.0,
),
child: Text(
'Place Order',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
),
],
),
ListView.builder(
scrollDirection: Axis.vertical,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
primary: false,
itemCount: products.length,
itemBuilder: (ctx, i) => ProductItem(
products[i].id,
products[i].name,
products[i].size,
products[i].price,
products[i].image,
),
)
],
),
);
}
}
Looking at your code, you don't need the SingleChildScrollView widget. Just remove it. The listView is built with a scroll behaviour, you dont need to add it.
Please, let me know if you meant something else and I can help.
If you still have the Renderflex error, then wrap your Column widget inside a Flexible widget
Flexible(child: Column(children:[..

How to make infinity scroll layout in flutter? (Updated)

I'm trying to make listview using data from REST API, the position is below my image , but the layout reach its limit, so i can't create it , and showing this error
here my code, (Updated Code)
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:schoolofparentingalfa/assets/color/color.dart';
class Home extends StatefulWidget {
#override
Home2 createState() => Home2();
}
class Home2 extends State<Home> {
var colorsop = new Colorsop();
var apiconfig = new ApiConfig();
var apiClient = new ApiClient();
#override
void initState() {
super.initState();
}
//To call list from api
Future<List<Artikel>> getNews() async {
// future is used to handle the error when calling api > Future + async or await
var data = await http.get(
'https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=c4349a84570648eaa7be3cd673cc262b');
var jsonData = json.decode(data.body);
var newsData =
jsonData['articles']; //to retrieve data from articles array of api
List<Artikel> news = []; // create array
for (var data in newsData) {
//assign data into News model array list from articles array of api
Artikel newsItem = Artikel(
data['title'], data['description'], data['urlToImage']);
news.add(newsItem);
}
return news;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(children: <Widget>[
Positioned(
top: 0,
child: Container(
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.yellow[800],
child: Align(
alignment: Alignment.center,
child: Text("Halo, Selamat Datang", style: TextStyle(color: Colors.white, fontSize: 25),))),
),
Positioned(
top: 90,
bottom: 0,
right: 0,
left: 0,
child: Container(
width: MediaQuery.of(context).size.width,
height: 600,
decoration: BoxDecoration(
color: Colors.white,
),
child: GridView.count(
crossAxisCount: 1,
children: [
Container( // Container 1
child: Row(
children: <Widget>[
Image.asset(
'lib/assets/image/kelas_online.png',
height: 120,
width: 150,
),
Image.asset(
'lib/assets/image/tanyaahli.png',
height: 120,
width: 150,
),
],
),
),
Container( // Container 2
child: Row(
children: <Widget>[
Image.asset(
'lib/assets/image/workshop_online.png',
height: 120,
width: 150,
),
Image.asset(
'lib/assets/image/MitraSekolah.png',
height: 120,
width: 150,
),
],
),
),
Container( //Container 3
margin: EdgeInsets.only(top: 15, bottom: 30, left: 20),
padding: EdgeInsets.symmetric(horizontal: 15),
child: FutureBuilder(
future: getNews(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
//snapshot is same with response
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
// to retrieve data as all array indexes
itemBuilder: (BuildContext context, int index) {
// is same with holder
return InkWell(
// Inkwell is used to apply card view
onTap: () {
Artikel news = new Artikel(snapshot.data[index].post_link, snapshot.data[index].description, snapshot.data[index].post_image);//is used to onclick
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => new Details(news: news)
));
},
child: Card(
child: Row(
children: <Widget>[
Container(
width: 120.0,
height: 110.0,
child: ClipRRect(
//for corner radius
borderRadius:
BorderRadius.all(Radius.circular(8)),
//to retrieve image from array
child: snapshot.data[index].post_image == null
? Image.network(
'https://cdn2.vectorstock.com/i/1000x1000/70/71/loading-icon-load-icon-wait-for-a-wait-please-wait-vector-24247071.jpg')
: Image.network(
snapshot.data[index].post_image,
width: 100,
fit: BoxFit.fill,
),
),
),
Expanded(
child: ListTile(
//include title and subtitle
title: Text(snapshot.data[index].post_title),
subtitle: Text(snapshot.data[index].post_link == null
? 'Unknown Author'
: snapshot.data[index].post_link),
),
)
],
),
),
);
},
);
}
},
),
),
],
),
)
)
],),
);
}
}
}
class Details extends StatelessWidget{
final Artikel news;
Details({this.news}); // create constructor
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: Column(
children: <Widget>[
Stack( //little same with expanded
children: <Widget>[
Container(
height: 400,
child: Image.network('${this.news.post_image}',
fit: BoxFit.fill,),
),
AppBar(
backgroundColor: Colors.transparent,
leading: InkWell(
child: Icon(Icons.arrow_back_ios),
onTap: () => Navigator.pop(context),
),
elevation: 0,
)
],
),
Padding(
padding: const EdgeInsets.all(8),
child: Column(
children: <Widget>[
SizedBox( // for title
height: 10,
),
Text(
'${this.news.post_title}',
style: TextStyle(
color: Colors.black87,
fontWeight: FontWeight.bold,
fontSize: 20,
letterSpacing: 0.2,
wordSpacing: 0.6
),
),
SizedBox( // for description
height: 20,
),
Text(
this.news.post_link,
style: TextStyle(
color: Colors.black54,
fontSize: 16,
letterSpacing: 0.2,
wordSpacing: 0.3
),
)
],
),
)
],
),
),
),
);
}
}
class Artikel {
final String post_title;
final String post_link;
final String post_image;
//Alt+insert > constructor
Artikel(this.post_title, this.post_link, this.post_image);
}
Can anyone help me?
Updated Screenshot .............................................................................
you can replace the code and check
return Scaffold(
body: Stack(children: <Widget>[
Positioned(
top: 0,
child: Container(
height: 100,
width: MediaQuery.of(context).size.width,
color: Colors.yellow[800],
child: Align(
alignment: Alignment.center,
child: Text("Halo, Selamat Datang", style: TextStyle(color: Colors.white, fontSize: 25),))),
),
Positioned(
top: 90,
bottom: 0,
right: 0,
left: 0,
child: Container(
width: MediaQuery.of(context).size.width,
height: 600,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft:Radius.circular(20), topRight:Radius.circular(20)) ),
child:
GridView.count(
crossAxisCount: 2,
children: List.generate(5, (index) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: GridTile(child: Image.network("https://upload.wikimedia.org/wikipedia/commons/6/6d/Good_Food_Display_-_NCI_Visuals_Online.jpg"),),
);
}) ,),)
)
],),
);

How to get data from previous page flutter

I'm trying to build a page about description of a photo with this code:
import 'package:flutter/material.dart';
import 'description_widget.dart';
class ImageDescription extends StatefulWidget {
#override
_ImageDescriptionState createState() => _ImageDescriptionState();
}
class _ImageDescriptionState extends State<ImageDescription> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.white10,
elevation: 0,
leading: Container(
padding: EdgeInsets.fromLTRB(20, 20, 0, 0),
child: InkWell(
child: Hero(
tag: 'back',
child: Image.asset(
'assets/images/wp_back_button_icon.png',
height: 250,
),
),
onTap: () {
Navigator.pop(context);
},
),
),
actions: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(0, 20, 20, 0),
child: Hero(
tag: 'logo',
child: Image.asset(
'assets/images/wp_logo.png',
height: 250,
),
),
),
],
),
body: SingleChildScrollView(
child: imageDescription(
"assets/images/gallery/Image1.jpg",
"Tittle 1",
"Description 1.",
"Image1"),
),
);
}
}
Using this Widget that i've created:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
Widget imageDescription(String url, title, description, tag) {
return Container(
child: Column(
children: <Widget>[
Container(
child: Column(
children: <Widget>[
Center(
child: Text(title, style: TextStyle(fontSize: 30)),
),
Center(
child: Text("Let's educate in the fun way!"),
)
],
),
),
Container(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.all(10),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Hero(tag: tag, child: Image.asset(url)),
),
),
Container(
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Card(
child: Container(
margin: const EdgeInsets.all(10),
child: Text(
description,
textAlign: TextAlign.justify,
style: TextStyle(fontSize: 20),
),
),
),
)
],
),
)
],
),
);
}
But instead of manually adding the imageDescription(
"assets/images/gallery/Image1.jpg",
"Tittle 1",
"Description 1.",
"Image1"),
I want to get the variables from the image that i clicked on previous page :
import 'package:flutter/material.dart';
import 'image_description.dart';
import 'show_image.dart';
class Gallery extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.white10,
elevation: 0,
leading: Container(
padding: EdgeInsets.fromLTRB(20, 20, 0, 0),
child: InkWell(
child: Hero(
tag: 'back',
child: Image.asset(
'assets/images/wp_back_button_icon.png',
height: 250,
),
),
onTap: () {
Navigator.pop(context);
},
),
),
actions: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(0, 20, 20, 0),
child: Hero(
tag: 'logo',
child: Image.asset(
'assets/images/wp_logo.png',
height: 250,
),
),
),
],
),
body: SafeArea(
child: Column(
children: <Widget>[
Container(
child: Text(
'AR Gallery',
style: TextStyle(fontSize: 30),
),
),
Container(
child: Text("Let's educate in the fun way"),
),
Expanded(
child: SizedBox(
height: double.infinity,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 3,
children: <Widget>[
InkWell(
child: Stack(
children: <Widget>[
ShowImage(
url: "assets/images/gallery/Image1.jpg",
tag: "Image1",
title: "Title 1",
)
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageDescription()));
},
),
InkWell(
child: Stack(
children: <Widget>[
ShowImage(
url: "assets/images/gallery/Image2.jpg",
tag: "Image2",
title: "Title 2",
)
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageDescription()));
},
),
InkWell(
child: Stack(
children: <Widget>[
ShowImage(
url: "assets/images/gallery/Image3.jpg",
tag: "Image3",
title: "Title 3",
)
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageDescription()),
);
}),
],
),
),
),
],
),
),
);
}
}
using this widget:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class ShowImage extends StatelessWidget {
final String tag;
final String url;
final String title;
const ShowImage({Key key, this.tag, this.url, this.title}) : super(key: key);
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child:
Hero(tag: tag, child: Image.asset(url, fit: BoxFit.fitHeight)),
),
),
Container(
padding: const EdgeInsets.all(5),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Text(title,
style: TextStyle(
backgroundColor: Colors.deepOrange, color: Colors.white)),
),
)
],
);
}
}
or simply:
open gallery page
click an image
open image description page with title & image path of clicked image
Regards, Slim
I would recommend you to follow this tutorial.
For you this would mean:
Create a class that contains all the data you would like to pass:
class ImageData {
final String title;
final String url;
final String description;
final String tag;
Image(this.title, this.url, this.description, this.tag);
}
Set Up your ImageDescriptionScreen to require an Image object:
import 'package:flutter/material.dart';
import 'description_widget.dart';
import 'image_data.dart';
class ImageDescription extends StatefulWidget {
final ImageData imageData;
// In the constructor, require an Image Object.
ImageDescriptionScreen({Key key, #required this.imageData}) :
super(key: key);
#override
_ImageDescriptionState createState() => _ImageDescriptionState();
}
class _ImageDescriptionState extends State<ImageDescription> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.white10,
elevation: 0,
leading: Container(
padding: EdgeInsets.fromLTRB(20, 20, 0, 0),
child: InkWell(
child: Hero(
tag: 'back',
child: Image.asset(
'assets/images/wp_back_button_icon.png',
height: 250,
),
),
onTap: () {
Navigator.pop(context);
},
),
),
actions: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(0, 20, 20, 0),
child: Hero(
tag: 'logo',
child: Image.asset(
'assets/images/wp_logo.png',
height: 250,
),
),
),
],
),
body: SingleChildScrollView(
child: imageDescription(
widget.imageData.url,
widget.imageData.title,
widget.imageData.description,
widget.imageData.tag
),
),
);
}
}
Pass the image object when navigating to the new page:
Navigator.push(context, MaterialPageRoute(builder: (context) =>
ImageDescription(imageData: ImageData('title', 'url', 'description', 'tag'),)));
EDIT: I put my solution outlined below into dartpad, feel free to try it out there and copy & paste the code.
Short remarks to my dartpad solution:
All image data is maintained and contained in this list of ImageData Objects. Relevant information for other screens is passed via Navigator. With this solution you only need to maintain image data in this list. The grid view automatically expands if more items are added to the list.
final List<ImageData> imageList = [
ImageData(title: 'MacBook',url: 'https://picsum.photos/250?image=9',
description: 'this is a macbook', tag: 'macbook'),
ImageData(title: 'Deer',url: 'https://picsum.photos/250?image=1003',
description: 'this is a deer', tag: 'deer'),
];
Let me know if anything is unclear :)

I want to add a new element after my horizontal listview how can I add it

This is the projected picture that shows how I am able to add an element.
Below is my code in which I want to add an element so that if my list is not present it also shows the element and if it present then the element is the last element.
I have tried this in some different ways.
Can anyone please help me?
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'alllist.dart';
List<Alllist> _alllist = [];
List<Alllist> get alllist => _alllist;
class EduCategory extends StatefulWidget{
final String listcategory;
final int intp;
EduCategory({this.listcategory,this.intp});
#override
EduCategoryState createState() {
return new EduCategoryState();
}
}
class EduCategoryState extends State<EduCategory> {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Container(child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
widget.listcategory,
style: TextStyle(fontWeight: FontWeight.bold),
),
new Row(
children: <Widget>[
new Icon(Icons.play_arrow),
new Text("Watch All", style: TextStyle(fontWeight: FontWeight.bold))
],
)
],
),
Expanded(
child: new Padding(
padding: const EdgeInsets.only(top: 8.0),
child:new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('all list').where("listcategory",isEqualTo: widget.listcategory).snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return new Text("no");
if (snapshot.data.documents.length == 0) return InkWell(
child: Stack(
children: <Widget>[
new Container(
width: 80.0,
height: 80.0,
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
border: Border.all(color: Colors.blueGrey),
borderRadius: BorderRadius.circular(5.0),
image: new DecorationImage(
fit: BoxFit.fill,
image: new AssetImage("assets/Plus.png")),
),
margin: const EdgeInsets.symmetric(horizontal: 20.0),
// child: Text(name),
),
Padding(padding: EdgeInsets.only(top: 80.0,left: 20.0),
child: Text("Add Lession",style: TextStyle(fontWeight: FontWeight.bold,color: Colors.blueGrey),),
),
],
),
onTap: (){},
);
return new ListView(
scrollDirection: Axis.horizontal,
children: buildGrid(snapshot.data.documents)
);;
}
),
))
],
),
);
}
List<Widget> buildGrid(List<DocumentSnapshot> documents) {
List<Widget> _gridItems = [];
_alllist.clear();
for (DocumentSnapshot document in documents) {
_alllist.add(Alllist.fromDocument(document));
}
for (Alllist alllist in _alllist) {
_gridItems.add(buildGridItem(alllist));
}
return _gridItems;
}
Widget buildGridItem(Alllist alllist,) {
return widget.intp==0?
InkWell(
child: Stack(
children: <Widget>[
new Container(
width: 80.0,
height: 80.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.blue,width: 4.0,style: BorderStyle.solid),
image: new DecorationImage(
fit: BoxFit.fill,
image: new NetworkImage(
alllist.imageUrl)),
),
margin: const EdgeInsets.symmetric(horizontal: 20.0),
// child: Text(name),
),
Padding(padding: EdgeInsets.only(top: 80.0,left: 10.0),
child: Text(alllist.title,style: TextStyle(fontWeight: FontWeight.bold,color: Colors.blueGrey),),
),
],
),
onTap: (){},
):new Row(
children: <Widget>[
InkWell(
child: Stack(
children: <Widget>[
new Container(
width: 80.0,
height: 80.0,
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5.0),
image: new DecorationImage(
fit: BoxFit.fill,
image: new NetworkImage(
alllist.imageUrl)),
),
margin: const EdgeInsets.symmetric(horizontal: 20.0),
// child: Text(name),
),
Padding(padding: EdgeInsets.only(top: 80.0,left: 10.0),
child: Text(alllist.title,style: TextStyle(fontWeight: FontWeight.bold,color: Colors.blueGrey),),
),
],
),
onTap: (){},
)
]
);
}
}
You can use the ListView.builder with itemCount as snapshot.data.documents.length + 1.
Code sample:
new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('all list').where("listcategory",isEqualTo: widget.listcategory).snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return new Text("no");
var documentsLength = snapshot.data.documents.length;
ListView.builder(itemCount: documentsLength + 1, // +1 for last element
itemBuilder: (context, index) {
if (index == documentsLength) {
//last view which have plus button
} else {
return buildGridItem((Alllist.fromDocument(snapshot.data.documents[index]))
}
});
})
I think that you have to just add condition in itemBuilder checkout in below code;
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final List<int> items=[1,2,3,4,5,6];
#override
Widget build(BuildContext context) {
final title = 'Mixed List';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Container(
height: 100.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: items.length + 1 ,
itemBuilder: (context, index) {
if(index < items.length )
{ return Container(
color: Colors.blue,
width: 100.0,
padding: EdgeInsets.all(8.0),
child: new Center(
child: new Text(index.toString()),
),
);
}
else {
return new Container(
color: Colors.blue,
width: 100.0,
child: new Center(
child: new Text(index.toString() + "differnt"),
),
);
}
},
),
),
),
);
}
}