How to get two rows in ListView.separated - flutter

I wanted to achieve the following output but instead of one row in a column, I want to show two rows in a column using ListView.separated. How can I get it? ListView.separated does not have any option to display 2 rows.
Scaffold(
body: ListView.separated(
itemBuilder: (context, position) {
return Container(
height: 40.0,
color: Colors.white,
child: Text('Your text goes here'),
);
},
separatorBuilder: (context, position) {
return Container(
color: Colors.red,
child: Text('Divider'),
);
},
itemCount: 20,
),
));

To achieve this, you can use the Row widget. In order to expand the Text widgets, you can wrap them with Expanded.
Full working example, based on your code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ListView.separated(
itemBuilder: (context, position) {
return Container(
height: 40.0,
color: Colors.white,
child: Text('Your text goes here'),
);
},
separatorBuilder: (context, position) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
color: Colors.red,
child: Text(
'Divider 1',
textAlign: TextAlign.center,
),
),
),
Expanded(
child: Container(
color: Colors.red,
child: Text(
'Divider 2',
textAlign: TextAlign.center,
),
),
),
],
);
},
itemCount: 20,
),
),
);
}
}

Related

Vertical and Horizontal Coordinated Scrolling of Independent Lists

I have joined tables of data that I need to scroll together on both horizontal and vertical axis, with heading First Row that should not scroll with vertical data, but should scroll with horizontal.
You can see from my video that my simplified example below will scroll as desired vertically, but the rows, being independent do not scroll horizontally together as needed. The question is how to scroll each independent list horizontally together without losing the vertical functionality. The number of rows and columns is variable and can be quite large. My example code below is simplified to illustrate the behavior.
The below is a complete project example that can be cut and pasted into a dartpad flutter project or just click here: https://dartpad.dev/?id=6c4ea40ceee87ce9de4bcfe38ba0b750
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: MyWidget(),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
List listDates = ['Jan', 'Feb', 'Mar', 'Apr'];
Map<String, List> all = {
'Todd': [1,2,3,4],
'Mary': [5,6,7,8],
'Henry': [9,10,11,12],
};
List<String> names = [];
all.forEach((key,value) {
names.add(key);
});
return Column(
children: [
SizedBox(
height: 200,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const SizedBox(
height: 200,
width: 200,
),
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: listDates.length,
itemBuilder: (context, index) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 200,
child: Center(
child: Text(
listDates[index],
style: const TextStyle(
fontWeight: FontWeight.w600,
),
maxLines: 1,
textAlign: TextAlign.center,
),
),
),
],
);
},),
),
],
),
),
Expanded(
child: ListView.builder(
itemCount: 3,
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
color: index.isOdd ? Colors.blue.withOpacity(.2) : Colors.grey.withOpacity(.2),
),
child: SizedBox(
height: 200,
width: double.infinity,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(
width: 200,
height: 200,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
names[index],
style: const TextStyle(
fontWeight: FontWeight.w500,
),
),
),
),
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: listDates.length,
itemBuilder: (context, index2) {
List ints = all[names[index]]!;
return SizedBox(
width: 200,
child: Center(
child: Text(
ints[index2].toString(),
style: const TextStyle(
fontWeight: FontWeight.w600,
),
maxLines: 1,
textAlign: TextAlign.center,
),
),
);
},
),
),
],
),
),
);
},
),),
],
);
}
}

I am not able to make my app scrollble, despite of having SingleChildScrollView in Flutter

In my app, i have used BlogTile and CategoryTile widgets (which were made by myself) and I am using them in Contaniers/Columns. When I used SingleChildScrollView with CategoryTile, and made axis as horizontal, it was working fine. But as soon as i use it for BlogTile, it doen't work. I am not able to scroll in my app vertically. But when i try to scroll vertically by clicking on the part between CategoryTile and BlogTile, it works. But when i try to scroll by clicking from anyb other section of it, it doesn't work. Please someone help me
Check this code -
import 'package:flutter/material.dart';
import 'package:news_app/helper/data.dart';
import 'package:news_app/helper/news.dart';
import 'package:news_app/models/article_model.dart';
import 'package:news_app/models/category_models.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<CategoryModel> categories = new List<CategoryModel>();
List<ArticleModel> articles = new List<ArticleModel>();
bool loading = true;
#override
void initState() {
// TODO: implement initState
super.initState();
categories = getCategories();
getNews();
}
getNews() async {
News newsClass = News();
await newsClass.getNews();
articles = newsClass.news;
setState(() {
loading = false;
print('Done');
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Flutter',
style: TextStyle(
color: Colors.black,
),
),
Text(
'News',
style: TextStyle(
color: Colors.blue,
),
),
],
),
//elevation: 2.0,
),
body: loading
? Center(
child: Container(
child: CircularProgressIndicator(),
),
)
: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(top: 10.0),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
///Categories
Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
height: 70.0,
child: ListView.builder(
itemCount: categories.length,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (context, index) {
return CategoryTile(
imageUrl: categories[index].imageUrl,
categoryName: categories[index].categoryName,
);
},
),
),
SizedBox(
height: 30.0,
),
///Blogs
SingleChildScrollView(
child: Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: articles.length,
itemBuilder: (context, index) {
return BlogTile(
imageUrl: articles[index].urlToImage,
title: articles[index].title,
desc: articles[index].description,
);
},
),
),
),
],
),
),
),
),
),
),
);
}
}
class CategoryTile extends StatelessWidget {
final imageUrl, categoryName;
CategoryTile({this.imageUrl, this.categoryName});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {},
child: Container(
margin: EdgeInsets.only(right: 16.0),
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(6.0),
child: Image.network(
imageUrl,
width: 120.0,
height: 160.0,
fit: BoxFit.cover,
),
),
Container(
alignment: Alignment.center,
width: 120.0,
height: 160.0,
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(6.0)),
child: Text(
categoryName,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w500,
fontSize: 14.0,
),
),
),
],
),
),
);
}
}
class BlogTile extends StatelessWidget {
final String imageUrl, title, desc;
BlogTile(
{#required this.imageUrl, #required this.desc, #required this.title});
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Image.network(imageUrl),
Text(title),
Text(desc),
],
),
);
}
}
I think the issue here is that you're giving unbounded height and width to some of the ScrollViews.
First off, don't use multiple scrolling widgets nested inside one another. But if you want to do that, try wrapping each of your scrollview within a Container like this:
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
height: 50.0,
width: 50.0,
child: SingleChildScrollView(
child: ...,
),
),
),
What I'd also suggest is that instead of using a SingleChildScrollView, use a ListView widget. It works almost the same and you can put multiple children inside it. A simple ListView() will work. Don't use ListView.builder or any other aggregate function.

A RenderFlex overflowed by 1443 pixels on the bottom

I am trying to make it scrollable...enter image description here For some reason its not not scrolling and i tried adding singleChildScrollview still not working.... Pls look at the picture to understand better... so i posted the full code so that you guys can help me better... This was the error i got "Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size. This is considered an error condition because it indicates that there is content that cannot be seen. If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView."
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:memoryblog/helper/authenticate.dart';
import 'package:memoryblog/services/auth.dart';
import 'package:memoryblog/services/database.dart';
import 'package:memoryblog/views/create_blog.dart';
class MemoryRoom extends StatefulWidget {
#override
_MemoryRoomState createState() => _MemoryRoomState();
}
class _MemoryRoomState extends State<MemoryRoom> {
AuthMethod authMethod = new AuthMethod();
DatabaseMethods databaseMethod = new DatabaseMethods();
Stream blogsStream;
Widget BlogsList(){
return Container(
child: blogsStream != null ? Column(
children: <Widget>[
StreamBuilder(
stream: blogsStream,
builder: (context, snapshot){
if(snapshot.data == null) return CircularProgressIndicator();
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index){
return BlogsTile(
authorName: snapshot.data.documents[index].data['memoryName'],
title: snapshot.data.documents[index].data['title'],
description: snapshot.data.documents[index].data['desc'],
imgUrl: snapshot.data.documents[index].data['imgUrl'],
);
}
);
},
)
],
) : Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
)
);
}
#override
void initState() {
// TODO: implement initState
databaseMethod.getData().then((result){
setState(() {
blogsStream = result;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
children: <Widget>[
Text(
"Memory"
),
Text(
"Blog",
style: TextStyle(
color: Colors.blue
),
)
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
actions: <Widget>[
GestureDetector(
onTap: (){
authMethod.signOut();
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => Authenticate()
));
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Icon(Icons.power_settings_new)),
)
],
),
body: BlogsList(),
floatingActionButton: Container(
padding: EdgeInsets.symmetric(vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => CreateBlog()
));
},
child: Icon(Icons.add),
)
],
),
),
);
}
}
class BlogsTile extends StatelessWidget {
String imgUrl, title, description, authorName;
BlogsTile({#required this.imgUrl, #required this.title, #required this.description, #required this.authorName,});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 16),
height: 170,
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(6),
child: CachedNetworkImage(
imageUrl: imgUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
)
),
Container(
height: 170,
decoration: BoxDecoration(
color: Colors.black45.withOpacity(0.3),
borderRadius: BorderRadius.circular(6)
),
),
Container(
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
title,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
SizedBox(height: 4,),
Text(
description,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w400),
),
SizedBox(height: 4,),
Text(authorName)
],
),
)
],
),
);
}
}
Use ListView in place of the column. OR
Wrap Column with SingleChildScrollView
return Container(
child: blogsStream != null
? ListView(
children: <Widget>[
StreamBuilder(
stream: blogsStream,
builder: (context, snapshot) {
if (snapshot.data == null) return CircularProgressIndicator();
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return BlogsTile(
authorName:
snapshot.data.documents[index].data['memoryName'],
title: snapshot.data.documents[index].data['title'],
description:
snapshot.data.documents[index].data['desc'],
imgUrl: snapshot.data.documents[index].data['imgUrl'],
);
});
},
)
],
)
: Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);

Listview not showing inside a Row in Flutter

I am trying to show a listview after some texts in a column. The text shows properly inside the first Row until I add a listview inside the next row. Everything disappears after adding the ListView.
Here is the Code:
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text(
"Prayer Time",
style: TextStyle(fontSize: 20, fontWeight:
FontWeight.normal),
),
],
),
Row(
children: <Widget>[myList()],
),
],
),
),
floatingActionButton: FloatingActionButton(
tooltip: 'Add Alarm',
child: Icon(Icons.add),
backgroundColor: const Color(0xff0A74C5),
),
);
}
Expanded myList() {
return Expanded(
child: ListView.builder(
itemBuilder: (context, position) {
return Card(
child: Text(androidVersionNames[position]),
);
},
itemCount: androidVersionNames.length,
)
);
}
}
change like this:
Expanded(
child: Row(
children: <Widget>[myList()],
),
),
Your ListView should have a fixed Size. Try to wrap the ListView inside a Container.
I run your code and fixed it. Replace your myList() with this code bellow:
Expanded myList() {
return Expanded(
child: Container(
width: double.infinity,
height: 200,
child: ListView.builder(
itemBuilder: (context, position) {
return Card(
child: Text(androidVersionNames[position]),
);
},
itemCount: androidVersionNames.length,
),
)
);
}

Handle listview item height?

So i have this script which is build a listview
class NewProductsLists extends StatelessWidget {
final List<NewProducts> newlist;
NewProductsLists({Key key, this.newlist}) : super(key: key);
final formatCurrency =
new NumberFormat.simpleCurrency(locale: "id", decimalDigits: 2);
#override
Widget build(BuildContext context) {
return Expanded(
child: ListView.builder(
itemCount: newlist.length,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
print("Product detail");
},
child: Card(
child: Container(
width: MediaQuery.of(context).size.width * 0.50,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Image.network(
Configuration.url +
"assets/app_assets/" +
newlist[index].productImage,
width: 90,
height: 90,
filterQuality: FilterQuality.low),
ListTile(
title: Center(
child: Text(
newlist[index].productName,
style: TextStyle(fontSize: 18),
)),
subtitle: Center(
child: Text(
formatCurrency.format(
int.parse(newlist[index].productPrice)),
style: TextStyle(color: Colors.red, fontSize: 15),
)),
),
],
)),
),
);
}));
}
}
and the result looks like this
[
As you can see the card is expanding so hard. I know it is because the Expanded widget. Is it possible to make the card wrap_content ?
For horizontal list view needs fixed height if its not going to be vertical scrollable view you can use Expanded widget with varying flex to get it working.
Working build widget by using expanded widget.
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
centerTitle: false,
title: const Text('November'),
),
body: new Container(
child: Column(
children: <Widget>[
new Expanded(flex: 1,child: new Container(color: Colors.grey[300],),),
Expanded(flex: 2,
child: ListView.builder(
itemCount: 10,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
print("Product detail");
},
child: Card(
child: Container(
width: MediaQuery.of(context).size.width * 0.50,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Image.network(
'https://homepages.cae.wisc.edu/~ece533/images/watch.png',
width: 90,
height: 90,
filterQuality: FilterQuality.low),
ListTile(
title: Center(
child: Text(
'item Name ${index}',
style: TextStyle(fontSize: 18),
)),
subtitle: Center(
child: Text(
'\$10',
style: TextStyle(
color: Colors.red, fontSize: 15),
)),
),
],
)),
),
);
}),
),
new Expanded(flex: 3,child: new Container(color: Colors.amber[100],),),
],
)));
}
Result screen
Let me know if it suits your requirement.