A build function returned null,The offending widget is: StreamBuilder<QuerySnapshot> - flutter

Im new to flutter. Im trying to get items from firestore to be shown in Listview on the app but getting "build function returned null.The offending widget is: StreamBuilder,Build functions must never return null". I just want the list 'post' from firstore shown in listview
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Post App',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(0xff543b7a),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(FontAwesomeIcons.hamburger),
),
),
body: StreamBuilder(
stream: Firestore.instance.collection('post').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
Text('Loading');
} else {
return ListView.builder(
itemCount: snapshot.data.document.length,
itemBuilder: (context, index) {
DocumentSnapshot myPost = snapshot.data.documents[index];
return Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: 350.0,
child: Padding(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Material(
color: Colors.white,
elevation: 14.0,
shadowColor: Color(0x802196f3),
child: Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: 200.0,
child: Image.network(
'${myPost['image']}',
fit: BoxFit.fill,
),
),
SizedBox(
height: 10.0,
),
Text('${myPost['title']}'),
SizedBox(
height: 10.0,
),
Text('${myPost['subtitle']}'),
],
),
),
),
)
],
);
},
);
},
},
),
);
}
}
[enter image description here][1]
[1]: https://i.stack.imgur.com/QeSyi.png
A build function returned null.The offending widget is: StreamBuilder.Build functions must never return null.

You missed return:
builder: (context, snapshot) {
if (!snapshot.hasData) {
Text('Loading'); // <---- no return here
} else {
return ListView.builder(
itemCount: snapshot.data.documents.length, // <---- documents here
itemBuilder: (context, index) {
DocumentSnapshot myPost = snapshot.data.documents[index];

Related

Images dose not display on the screen instead it shows loading icon

I used a grid view list in order to show some items in another list that contain images
and doesn't show the items, instead it shows the loading icon
this is my code:
import 'package:flutter/material.dart';
import 'package:sct/list/list.dart';
class badriya2 extends StatefulWidget {
#override
State<badriya2> createState() => _badriya2State();
}
class _badriya2State extends State<badriya2> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
"She codes",
),
),
body: FutureBuilder(builder: (context, AsyncSnapshot snapshot) {
height:
MediaQuery.of(context).size.height;
width:
MediaQuery.of(context).size.width;
if (snapshot.hasData) {
List resList = snapshot.data;
child:
Expanded(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
crossAxisSpacing: 5.0,
mainAxisSpacing: 5.0,
),
itemCount: resList.length,
itemBuilder: (context, index) {
primary:
true;
padding:
const EdgeInsets.all(20);
shrinkWrap:
true;
children:
<Widget>[
Card(
child: Center(
child: CircleAvatar(
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.asset(
list[0].image,
),
),
minRadius: 50,
maxRadius: 75,
),
),
elevation: 10,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
),
];
return Center(child: CircularProgressIndicator());
}));
}
return Center(child: CircularProgressIndicator());
}));
}
}
and this is the list :
import 'package:flutter/cupertino.dart';
List list = [
{
Image.asset('assets/images/butterfly.jpg'),
},
{
Image.asset('assets/images/flower.jpg'),
},
{
Image.asset('assets/images/glass.jpg'),
},
{
Image.asset('assets/images/sun.jpg'),
},
{
Image.asset('assets/images/lighting.jpg'),
},
{
Image.asset('assets/images/phone.jpg'),
},
{
Image.asset('assets/images/eye.jpg'),
},
{
Image.asset('assets/images/photo1.jpg'),
},
];
the point of this code is not to duplicate the items in grid view, I want to write in one line
Add future method onfuture inside FutureBuilder.
return FutureBuilder(
future: yourFutureMethod(),
builder: (context, snapshot) {...},
);
You use the Future Builder but you didn't mention any future. Set the Future
import 'package:flutter/material.dart';
import 'package:sct/list/list.dart';
class badriya2 extends StatefulWidget {
#override
State<badriya2> createState() => _badriya2State();
}
class _badriya2State extends State<badriya2> {
var dummy;
#override
void initState() {
super.initState();
dummy = _getimages();
print("data ${dummy}");
}
_getimages() async {
var imagelist = await list;
print(imagelist);
return imagelist;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
"She codes",
),
),
body: FutureBuilder(
future: _getimages(),
builder: (context, AsyncSnapshot snapshot) {
if(snapshot.hasError) print(snapshot.error);
return snapshot.hasData
?GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 5.0,
mainAxisSpacing: 5.0,
),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
List reslist = snapshot.data;
return Column(
children: [
Card(
child: Center(
child: Container(
width: 100,
height: 100,
child: CircleAvatar(
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.network(reslist[index].toString(),)
),
minRadius: 50,
maxRadius: 75,
),
),
),
elevation: 10,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
),
],
);
}
):
Center(
child:CircularProgressIndicator()
);
}
)
);
}
}
And please assign proper list of data
import 'package:flutter/cupertino.dart';
List list= [
"https://dlanzer.com/flutter_api/assets/uploads/images/farm_2021-10-25%2005:09:48am.png",
"https://dlanzer.com/flutter_api/assets/uploads/images/farm_2021-10-25%2005:09:11am.png",
"https://dlanzer.com/flutter_api/assets/uploads/images/farm_2021-10-19%2002:51:18pm.png",
"https://dlanzer.com/flutter_api/assets/uploads/images/farm_2021_10_12_04_30_13_pm.png",
];
Here I use network images You change to asset images

How to create List View builder item like this in flutter?

I am new to Flutter. Please guide me how can i add a button at the last index of listview builder. I don't understand how can i attach the button at the last position.
import 'package:flutter/material.dart';
class ListCheck extends StatefulWidget {
#override
_ListCheckState createState() => _ListCheckState();
}
class _ListCheckState extends State<ListCheck> {
List<Color> colors=[Colors.black,Colors.green,Colors.yellow,Colors.red,Colors.blueGrey,
Colors.deepPurple,Colors.cyan,Colors.purple,Colors.orange,Colors.pink];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
itemCount: colors.length,
itemBuilder: (context,item){
return Container(
height: 100,
width: 100,
child: Card(
child: Center(
child: Text("Abc",style: TextStyle(color: Colors.white),),
),
),
);
}),
);
}
}
import 'package:flutter/material.dart';
class ListCheck extends StatefulWidget {
#override
_ListCheckState createState() => _ListCheckState();
}
class _ListCheckState extends State<ListCheck> {
List<Color> colors=[Colors.black,Colors.green,Colors.yellow,Colors.red,Colors.blueGrey,
Colors.deepPurple,Colors.cyan,Colors.purple,Colors.orange,Colors.pink];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
itemCount: colors.length+1,
itemBuilder: (context,item){
if (colors.length== item) {
return Container(
height: 100,
width: 100,
child: Card(
child: Center(
child: Icon(Icons.add),),
),
),
) }
return Container(
height: 100,
width: 100,
child: Card(
child: Center(
child: Text("Abc",style: TextStyle(color: Colors.white),),
),
),
);
}),
);
}
}

Problem wiht multiple listviews inside column / Horizontal viewport was given unbounded height

I am still new to flutter and trying to achieve a following layout of two listviews, one is displaying the top news articles, another one is showing further articles. The first one is supposed to be horizontal, the second one vertical, but both are element of one single scrollview.
Something like this here:
I am using cubit to have different states, while it loads the articles, but in combination with the SingleChildScrollView, I can never get the second, vertical listview to display, I always get
"Horizontal viewport was given unbounded height."
How can i fix this?
Also, if two widgets share the same list fetched by a bloc, is there a good way to reuse that list, instead of having two BlocBuilders?
Here is my code:
body.dart
class Body extends StatelessWidget {
Widget buildArticleWidgets(List<Article> articles) {
return ListView.builder(
scrollDirection: Axis.horizontal,
primary: false,
itemBuilder: (BuildContext context, int index) {
return ArticleWidget(articles[index]);
},
itemCount: 5,
);
}
Widget _buildSmallArticleWidgets(List<Article> articles) {
return ListView.builder(
scrollDirection: Axis.horizontal,
primary: false,
itemBuilder: (BuildContext context, int index) {
return SmallArticle(articles[index]);
},
itemCount: 5,
);
}
#override
Widget build(BuildContext context) {
final articleCubit = context.bloc<ArticlesCubit>();
articleCubit.getArticles();
return Column(
children: [
CategoriesTab(),
Expanded(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.centerLeft,
child: Text('Popular News',
style: TextStyle(
color: Colors.black,
fontSize: 18,
)),
),
SizedBox(
height: 200,
child: BlocBuilder<ArticlesCubit, ArticlesState>(
builder: (context, state) {
if (state is ArticlesInitial) {
return Container();
} else if (state is ArticlesLoading) {
return Container();
} else if (state is ArticlesLoaded) {
return buildArticleWidgets(state.articles);
}
return Container();
},
)),
Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.centerLeft,
child: Text('More News',
style: TextStyle(
color: Colors.black,
fontSize: 18,
)),
),
BlocBuilder<ArticlesCubit, ArticlesState>(
builder: (context, state) {
if (state is ArticlesInitial) {
return Container();
} else if (state is ArticlesLoading) {
return Container();
} else if (state is ArticlesLoaded) {
return _buildSmallArticleWidgets(state.articles);
}
return Container();
},
)
],
)))
],
);
}
}
home_screen.dart
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: SvgPicture.asset("assets/icons/menu.svg"),
onPressed: () {
Scaffold.of(context).openDrawer();
},
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
);
},
),
title: Text(
'NewsLab',
),
centerTitle: true,
),
drawer: Drawer(),
backgroundColor: Colors.white,
body: Body(),
);
}
}
and
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "NewsLab",
theme: ThemeData(
scaffoldBackgroundColor: Colors.transparent,
primaryColor: Colors.blue,
textTheme:
Theme.of(context).textTheme.apply(bodyColor: Colors.transparent),
visualDensity: VisualDensity.adaptivePlatformDensity),
home: BlocProvider(
create: (context) => ArticlesCubit(ArticlesRepository()),
child: HomeScreen(),
),
);
}
}
In the second Column widget in your body, use Expanded widget on the children widgets.

Flutter: Long Press on picture to get zoomed preview like Instagram

so I am currently having a grid of pictures and I want to implement a feature from instagram: If you longPress on one of the pictures, you get a a larger version of that picture appearing in the middle of the screen. If you stop pressing, the image dissapears.
I don't really need the code for that, but I just can't think of which widgets I should use.
Is there maybe a package for something like this? If not then how can I do it with Flutter standard widgets? Maybe using a dialog that appears on the longPress ?
Here's the improved vewrsion that resembles the same exact UX as of Instagram with blurred background.
We can achieve this using a combination of Stateful Widget, Stack and BackdropFliter, here is the sample code -
import 'dart:ui';
import 'package:flutter/material.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: 'Counter Demo',
theme: ThemeData.light(),
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blueGrey,
centerTitle: true,
title: Text("Demo App"),
),
body: Stacked(),
),
);
}
}
class Stacked extends StatefulWidget {
#override
_StackedState createState() => _StackedState();
}
class _StackedState extends State<Stacked> {
final List<String> images = [
"1.jpg",
"2.jpg",
"3.jpg",
"4.jpg",
"5.jpg",
"6.jpg",
"7.jpg",
"8.jpg",
"9.jpg",
"10.jpg",
];
bool _showPreview = false;
String _image = "assets/images/1.jpg";
#override
Widget build(BuildContext context) {
return SafeArea(
child: Stack(
children: [
GridView.builder(
itemCount: images.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onLongPress: () {
setState(() {
_showPreview = true;
_image = "assets/images/${images[index]}";
});
},
onLongPressEnd: (details) {
setState(() {
_showPreview = false;
});
},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
clipBehavior: Clip.hardEdge,
child: Image.asset("assets/images/${images[index]}"),
),
),
);
},
),
if (_showPreview) ...[
BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 5.0,
sigmaY: 5.0,
),
child: Container(
color: Colors.white.withOpacity(0.6),
),
),
Container(
child: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image.asset(
_image,
height: 300,
width: 300,
),
),
),
),
],
],
));
}
}
This is just a baseline example and there are endless possibilities you can modify this to achieve behavior you want.
Another simple way is we can build this by using StatefulWidget and IndexedStack -
import 'package:flutter/material.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: 'Counter Demo',
theme: ThemeData.light(),
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.blueGrey,
centerTitle: true,
title: Text("Demo App"),
),
body: Body(),
),
);
}
}
class Body extends StatefulWidget {
#override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<Body> {
final List<String> images = [
"1.jpg",
"2.jpg",
"3.jpg",
"4.jpg",
"5.jpg",
"6.jpg",
"7.jpg",
"8.jpg",
"9.jpg",
"10.jpg",
];
int _index = 0;
String _image = "assets/images/1.jpg";
#override
Widget build(BuildContext context) {
return SafeArea(
child: IndexedStack(
index: _index,
children: [
GridView.builder(
itemCount: images.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onLongPress: () {
setState(() {
_index = 1;
_image = "assets/images/${images[index]}";
});
},
onLongPressEnd: (details) {
setState(() {
_index = 0;
});
},
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
clipBehavior: Clip.hardEdge,
child: Image.asset("assets/images/${images[index]}"),
),
),
);
},
),
Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
),
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 400,
maxWidth: 400,
),
child: Image.asset(
_image,
),
),
),
)
],
),
);
}
}
You can check output for above code here.
You could use Peek and Pop https://pub.dev/packages/peek_and_pop
Is an implementation for Flutter based on the iOS functionality of the same name.

Flutter Cannot show List item in Drawar

I am new to flutter.
I am trying to create list view dynamically using server response JSON data using futureBuilder. The code writen by me while wathing YouTube videos, but I can't understand what is the mistake.
//It looks like your post is mostly code; please add some more details.//
main.dart
import 'package:flutter/material.dart';
import 'home.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: home(),
));
}
home.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
class home extends StatefulWidget {
home({Key key}):super();
#override
homepage createState() =>new homepage();
}
class homepage extends State<home>{
Color theme = Colors.lightBlue;
Color theme_text = Colors.white;
Future<List<category>> _getCategory() async {
var data = await http
.get("https://next.json-generator.com/api/json/get/VJ6EHYFO_");
debugPrint(data.body);
var jsondata = json.decode(data.body);
List<category> list = [];
for (var u in jsondata) {
category c = category(u['name'], u['id']);
list.add(c);
}
return list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: theme,
title: Text('SIMS Home Page'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.shopping_cart),
onPressed: () => debugPrint("search pressed"),
)
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text(
"Not Signed",
textAlign: TextAlign.center,
style: TextStyle(color: theme_text, fontSize: 20),
),
decoration: BoxDecoration(
color: theme,
),
),
FutureBuilder(
future: _getCategory(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text("Loading..."),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text(snapshot.data[index]),);
});
}
},
),
],
),
),
);
}
class category {
final name;
final id;
category(this.name, this.id);
}
You have to use shrinkwrap property of listView.builder to get it work. it will allow listview to grow only that much which is require.
Moreover, in text view you are assigning items directly you have to access name and id individually as shown in below code.
Container(
height: 150,
child: DrawerHeader(
child: Text(
"Not Signed",
textAlign: TextAlign.center,
style: TextStyle(color: theme_text, fontSize: 20),
),
decoration: BoxDecoration(
color: theme,
),
),
),
FutureBuilder(
future: _getCategory(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text("Loading..."),
),
);
} else {
return Container(
height: MediaQuery.of(context).size.height - 150,
child: ListView.builder(
shrinkWrap: true, //added line
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(snapshot.data[index]
.toString()), //accessing name from json
);
}),
);
}
},
),