how to creare Horizontal list in flutter - flutter

I am trying to develop a horizontal list view in flutter.
when ever I type scrollDirection: Axis.horizontal, and re run the program I have issues saying.
I tried rapping the whole with listview but also its not working
body: Container(
child:ListView.builder(
itemCount: _list.length,
itemExtent: 200.0,
itemBuilder: (context, i) {
final b = _list[i];
return new ListTile(
title: new Card(
elevation: 1.0,
child: new Container(
height: 293,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
blurRadius: 6,
color: Colors.black,
offset: Offset(4, 4))
]),
padding: EdgeInsets.all(1.0),
child:
Column(
children: <Widget>[
SizedBox(height: 4),
Padding(
child: Image.network(b.bikeimage),
padding: EdgeInsets.only(bottom: 0.0),
),
Padding(
child: Text(
b.name,
textAlign: TextAlign.right,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.black), ),
padding: EdgeInsets.only(left: 10),
),
],
),
),
),
onTap: () {
});
},
),
)

You got the error because your Container wasn't given a specified width and height.
The code below would work perfectly, Check it out,
body: Container(
// give your container any desired height
height: 500,
// give your container any desired width
width: double.infinity,
child: ListView.builder(
// set the scroll direction to horizontal for a horizontal list
scrollDirection: Axis.horizontal,
...
// the rest of your listview.builder code here
...
),
);
Hope this helps.

It looks like your container has no height or width constraints so it can't be drawn.

You havent mentioned scrollaxisdirection in your code add that and try. For further refer
https://pusher.com/tutorials/flutter-listviews

you can use below class for building listview in horizontal or vertical mode:
import 'package:flutter/material.dart';
class HorizontalListView extends StatefulWidget {
HorizontalListView({this.items, this.horizontal, this.width, this.height});
final List<Widget> items;
final bool horizontal;
final double width;
final double height;
#override
_HorizontalListState createState() {
// TODO: implement createState
return _HorizontalListState();
}
}
class _HorizontalListState extends State<HorizontalListView> {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
height: widget.height > 0 ? widget.height : 200.0,
child: ListView(
scrollDirection: widget.horizontal ? Axis.horizontal : Axis.vertical,
children: widget.items,
));
}
#override
void initState() {
super.initState();
}
}

Related

Drawer with ListViewBuilder and Header in Flutter

I'm trying to make a drawer widget that uses a ListViewBuilder to populate itself based on a list injected into the ViewModel.
However, I'm having issues getting it to play ball.
I've wrapped the LVB in a SizedBox to provide it with vertical bounds (since it was throwing a bunch of errors, as suggeested by another answer, and that's stopped those, but now I'm getting an overflow.
The header also doesn't fill out the width anymore either.
class MainDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Consumer<MainDrawerViewModel>(builder: (context, model, child) {
return Drawer(
child: Column(
children: [
DrawerHeader(
decoration: const BoxDecoration(color: ThemeColors.primaryDark),
child: Text(S.current.drawerTitle, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 30)),
),
SizedBox(
height: double.maxFinite,
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: model.mainDrawerItems.length,
itemBuilder: (_, index) {
final drawerItem = model.mainDrawerItems[index];
return ListTile(
leading: drawerItem.icon,
title: Text(drawerItem.title, style: Theme.of(context).textTheme.headline6),
selected: model.currentScreen == drawerItem.screen,
selectedTileColor: ThemeColors.selectedDrawerItem,
onTap: () {
model.selectScreen(drawerItem.screen);
Navigator.pop(context);
},
);
}),
),
],
));
});
}
}
This feels like something that should be pretty easy... What am I missing here?
Use Expanded widget on listView instead of height: double.maxFinite,
Expanded(
child: ListView.builder(
padding: EdgeInsets.zero,
double.maxFinite = 1.7976931348623157e+308; and it is equal to 1.7976931348623157 × 10^308 which is too big. and the overflow happens.
For header, you can wrap With SizedBox and provide width: double.maxFinite,. Also you can just use a container with decoration like
class MainDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: [
Container(
width: double.maxFinite,
height: 200, // based on your need
decoration: const BoxDecoration(color: Colors.amber),
padding: EdgeInsets.only(left: 16, top: 16),
child: Text(
"S.cu ",
style: TextStyle(
color: ui.Color.fromARGB(255, 203, 19, 19),
fontWeight: FontWeight.bold,
fontSize: 30),
),
),
Expanded(
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: 3,
itemBuilder: (_, index) {
return ListTile(
leading: Icon(Icons.abc_outlined),
title: Text("drawerItem.title",
style: Theme.of(context).textTheme.headline6),
selected: true,
onTap: () {},
);
}),
),
],
));
}
}

List Tiles out of container when scrolling

I have a ListViewBuilder inside a container in my UI when I scroll the list tiles get out of the container like so :
This my code :
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
child: Container(
margin: const EdgeInsets.only(
left: 30, right: 30, bottom: 20),
width: getProportionateScreenWidth(600),
height: getProportionateScreenHeight(300),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(17),
topRight: Radius.circular(17),
bottomLeft: Radius.circular(17),
bottomRight: Radius.circular(17)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: ListView.builder(
shrinkWrap: true,
physics: const ScrollPhysics(),
itemCount: snapshot.data!.perimeters.length,
itemBuilder: (context,index){
return PerimListTile(
perimID: snapshot.data!.perimeters[index].perimeterId.toString(),
perimLabel: snapshot.data!.perimeters[index].label,
);
})),
],
),
),
)
I want the list tiles to stay inside the container even while scrolling , if anyone knows how to solve the issue I'd be grateful , thank you in advance.
Problem
I do not know the details about getProportionateScreenHeight you used but I assume that it returns a double value.
The ListView inside the Column is constrained by the height of the container through that.
Solution
Remove the height of the container and try mainAxisSize: MainAxisSize.min on Column.
Solve
[1] Use the clip behavior parameter in container Widget. And set it to hardEdge
clipBehavior: Clip.hardEdge,
[2] Wrap the ListTile Widget with Card widget to make the cards inside the Container.
Card(child: ListTile());
Demo
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MyHome());
}
class MyHome extends StatelessWidget {
const MyHome({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Ans(),
);
}
}
class Ans extends StatefulWidget {
const Ans({super.key});
#override
State<Ans> createState() => _AnsState();
}
class _AnsState extends State<Ans> {
List<String> charName = [
'Rio',
'Tokyo',
'Berlin',
'Stockhome',
'Lisbon',
'Sergio',
'Martin'
];
List<String> charGender = [
'male',
'female',
'male',
'female',
'female',
'male',
'male'
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Tile Wrapper"),
),
body: SizedBox(
height: double.infinity,
width: double.infinity,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 100.0),
child: Container(
height: 400,
width: 300,
/// Clipping the inner View Condition
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.2),
border: Border.all(color: Colors.black),
color: Colors.amberAccent,
),
child: ListView.builder(
itemCount: charGender.length,
itemBuilder: ((BuildContext context, int index) {
return Padding(
padding: EdgeInsets.only(top: 20.0),
//// Wrap the ListTile with Card Widget...
child: Card(
child: ListTile(
title: Text(
charName[index],
style: TextStyle(fontSize: 18.0),
),
subtitle: Text(
charGender[index],
style: TextStyle(fontSize: 18.0),
),
tileColor: Colors.brown,
leading: CircleAvatar(
radius: 20, child: Icon(Icons.person_rounded)),
),
),
);
})),
),
),
],
),
),
);
}
}
Sample

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.

Flutter ListView not scrolling (I feel like I've tried every solution on the internet)

If I drag and hold my finger down I can see a few items that are below the cutoff of the screen but as soon as I let go, it just bounces back to the top. I tried using SingleChildScrollView places, tried setting primary = true, and a bunch of other stuff that didn't help. I'm fairly new to flutter so any help would be appreciated!! Let me know if any more info is needed.
Here is my code:
import 'package:flutter/material.dart';
import 'package:drink_specials/models/restaurant.dart';
import 'package:drink_specials/screens/home/restaurant_list.dart';
class RestaurantNameTextStyle {
static TextStyle display5(BuildContext context) {
return Theme.of(context).textTheme.headline2.copyWith(color: Colors.white);
}
}
class RestaurantTypeTextStyle {
static TextStyle display5(BuildContext context) {
return Theme.of(context).textTheme.headline6.copyWith(color: Colors.white);
}
}
class RestaurantDetail extends StatelessWidget {
final Restaurant restaurant;
RestaurantDetail({Key key, #required this.restaurant}) : super(key: key);
#override
Widget build(BuildContext context) {
final topContentText = Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 100.0),
Text(
restaurant.name,
style: RestaurantNameTextStyle.display5(context),
),
SizedBox(height: 10.0),
Expanded(
flex: 6,
child: Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(
restaurant.restaurant_type,
style: RestaurantTypeTextStyle.display5(context),
))),
],
);
final topContent = Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10.0),
height: MediaQuery.of(context).size.height * 0.5,
decoration: new BoxDecoration(
image: new DecorationImage(
image: NetworkImage(restaurant.photo),
fit: BoxFit.cover,
),
)),
Container(
height: MediaQuery.of(context).size.height * 0.5,
padding: EdgeInsets.all(40.0),
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Color.fromRGBO(58, 66, 86, .9)),
child: Center(
child: topContentText,
),
),
Positioned(
left: 8.0,
top: 60.0,
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, color: Colors.white),
),
)
],
);
final bottomContent = Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(8.0),
child: Center(
child: ListView.builder(
scrollDirection: Axis.vertical,
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
itemCount: restaurant.specials.length,
itemBuilder: (context, index) {
final item = restaurant.specials[index];
return Card(
elevation: 8.0,
margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
child: Container(
decoration: BoxDecoration(color: Color.fromRGBO(58, 66, 86, 1.0)),
child: ListTile(
contentPadding: EdgeInsets.symmetric(horizontal:20, vertical:10),
title: Text(item, style: TextStyle(color: Colors.white)),
)
),
);
}
),
),
);
return Scaffold(
body: Column(
children: <Widget>[
topContent,
Expanded(
child: bottomContent,
),
],
),
);
}
}
There is a ListView inside a SingleChildScrollView and both of them are scrollable. Scrolling on one of them should be disabled.
As they already explained. If you have a ListView.builder, you don't need SingleChildScrollView.
Try removing SingleChildScrollView. The code should look like this:
Scaffold(
body: Column(
children: <Widget>[
topContent,
Expanded(
child: bottomContent,
),
],
),
);
ListView already have scroll behavior so you won't need some SingleChildScrollView

How to constrain widget with a listview to the size of their children?

I have this SectorWidget that I meant it to be something decoupled.
I will pass to it a list of views (of the same height) but I wouldn't like to specify the height hardcoded inside ListView nor outside. I would like it to occupy the same height of widgets, something like wrap_content in Android. But I tried a lot of ways (like this or this) after search and cannot achieve this. Is there a way to do that in my specific case?
import 'package:flixapp/colors.dart';
import 'package:flutter/material.dart';
class SectorWidget extends StatelessWidget {
final SectorViewModel viewModel;
SectorWidget(this.viewModel);
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
child: Material(
color: Colors.transparent,
child: InkWell(
splashColor: kSplashColor,
onTap: () {},
child: Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text(
viewModel.title,
style: TextStyle(
fontWeight: FontWeight.w600,
color: Colors.black54,
fontSize: 30),
),
),
),
),
),
decoration: BoxDecoration(
color: viewModel.titleBackgroundColor ?? Colors.amber),
),
Container(
color: Colors.red,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: viewModel.data?.length ?? 0,
itemBuilder: (BuildContext context, int index) {
var data = viewModel.data;
if (data.isNotEmpty) return viewModel.data[index];
},
),
)
],
);
}
}
class SectorViewModel {
String title;
Color titleBackgroundColor;
List<Widget> data;
SectorViewModel({this.title, this.titleBackgroundColor, this.data});
}
When I understand you correctly, you want the root Column widget to match the size of it's children. For this, simply pass in mainAxisSize: MainAxisSize.min (the default is MainAxisSize.max - which I find a bit annoying as well, but anyway.)
also: There is no need for width: MediaQuery.of(context).size.width, in the child Container.. just tell the parent Column() to stretch it's children cross axis: crossAxisAlignment: CrossAxisAlignment.stretch.