When I try to add listview, its always gives me errors. Like:
RenderBox was not laid out: RenderRepaintBoundary#dab18 NEEDS-LAYOUT NEEDS-PAINT
Failed assertion: line 1982 pos 12 : 'hasSize'
The relevant error-causing widget was Column
I tried to add shrinkwrap to listview but it doesn't work too. When I delete my listview its works fine but I need to add it. What am I making wrong? Thanks for all your help! My code :
SliverToBoxAdapter(
child: Container(
child: Column(children: [
Container(
width: double.infinity,
child: Stack(
children: [
CorneredImage(
child: Image(
image: AssetImage(
'assets/images/phone-call.png',
),
),
),
Positioned.fill(
child: Container(
decoration: //some decors
),
),
Positioned.fill(
child: Container(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.all(24),
child: FractionallySizedBox(
widthFactor: 0.7,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: Column(
children: [
Text(
"Dilediğiniz Yerden Bağlanın!",
),
SizedBox(height: 10),
Text(
"Terapizone, ihtiyacınız olduğu her an size destek olmak için yanınızda!",
),
],
),
),
Align(
alignment: Alignment.bottomLeft,
child: ElevatedButton(
onPressed: () {},
child: Text("Terapiye Başla"),
)
],
),
),
),
),
)
],
),
),
Flexible( //When I add that part its not working anymore. List is simple String list
child: ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) => Text(list[index]))),
]),
),
),
Try This,
CustomScrollView( // Wrap SliverToBoxAdapter with CustomScrollView
shrinkWrap: true,
slivers: <Widget>[
SliverToBoxAdapter(
child: Container(
child: Column(mainAxisSize: MainAxisSize.min, // give mainAxixsize
children: [
Container(
width: double.infinity,
child: Stack(
children: [
Image(
image: AssetImage(
'assets/images/phone-call.png',
),
),
Positioned.fill(
child: Container(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.all(24),
child: FractionallySizedBox(
widthFactor: 0.7,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Column(
children: [
Text(
"Dilediğiniz Yerden Bağlann!",
),
SizedBox(height: 10),
Text(
"Terapizone, ihtiyacnz olduğu her an size destek olmak için yannzda!",
),
],
),
),
Align(
alignment: Alignment.bottomLeft,
child: ElevatedButton(
onPressed: () {},
child: Text("Terapiye Başla"),
))
],
),
),
),
),
)
],
),
),
Flexible( //When I add that part its not working anymore. List is simple String list
child: ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) => Text(list[index]))),
]),
),
),
// SizedBox(height: 1) // <-- Divider
],
)
I have been trying to run the onTap() function from material package of flutter but it seems to throw me this error:
"The following assertion was thrown while handling a gesture:
Navigator operation requested with a context that does not include a Navigator."
I am in need of running this function to reach out to the called function of new screen in the application.
The code is below:
class _HomePageState extends State<dashboardpage> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Stack(
children: <Widget>[
Container(
height:130*.99,
decoration: BoxDecoration(
image: DecorationImage(
alignment: Alignment.center,
image: AssetImage('assets/bismillah.png'),fit: BoxFit.fitHeight,
)
),
),
SafeArea(
child: Padding(
padding: EdgeInsets.only(top: 0),
child: Column(
children:<Widget> [
Container(
height: 100.0,
child: Row(
children:<Widget> [
Center(
child: SizedBox(
width: 90.0,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end
)
],
),
),
Expanded(
child:GridView.count(
mainAxisSpacing: 10,
crossAxisSpacing: 10,
primary: false,
crossAxisCount: 2,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60),
child: InkWell(
child: Card(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset('assets/images/kafiroun/kafirun.jpg',height: 80),
Text('सूरा अल काफिरून',style: TextStyle(fontWeight: FontWeight.bold,color: Colors.black87))
]
),
),
shape:RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)
),
elevation: 5.0,
),
onTap:(){
Navigator.push(context, MaterialPageRoute(builder: (context)=> kafiroun()));
},
)
),
),
),
)
]
);
}
}
This is the code specimen and the code is stuck on onTap() line.
Please help me!
Use GestureDetector
GestureDetector(onTap:(){
Navigator.push(context, MaterialPageRoute(builder: (context)=> kafiroun()));
},
child: Padding(
padding: const EdgeInsets.only(top: 60),
child: InkWell(
child: Card(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset('assets/images/kafiroun/kafirun.jpg',height: 80),
Text('सूरा अल काफिरून',style: TextStyle(fontWeight: FontWeight.bold,color: Colors.black87))
]
),
),
shape:RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)
),
elevation: 5.0,
),
)
),
)
I'm trying to implement a ListView of Rows like this:
And this is my code:
import 'package:flutter/material.dart';
import 'package:good_driver_app/common/ExpandedButton.dart';
class ServicePetrolPage extends StatefulWidget {
// HomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
// final String title;
#override
_ServicePetrolPage createState() => _ServicePetrolPage();
}
class _ServicePetrolPage extends State<ServicePetrolPage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text('Petrol'),
),
body: Container(
child: ListView(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
height: 50.0,
child: Row (
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo",
),
),
Flexible(
child: new Text(
"Location",
),
),
Flexible(
child: new Text(
"Distance",
),
),
Flexible(
child: new Text(
"\$",
),
),
Flexible(
child: new Text(
"Facilities",
),
),
],
),
),
)
],
),
),
Container(
padding: EdgeInsets.all(10),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
height: 50.0,
child: Row (
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo 1",
),
),
Flexible(
child: new Text(
"Johnson Rd",
),
),
Flexible(
child: new Text(
"0.2 KM",
),
),
Flexible(
child: new Text(
"\$12.45",
),
),
Flexible(
child: new Text(
"ATM, Restaurant",
),
),
],
),
),
)
],
),
),
Container(
padding: EdgeInsets.all(10),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
height: 50.0,
child: Row (
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo 2",
),
),
Flexible(
child: new Text(
"Hennessy Rd",
),
),
Flexible(
child: new Text(
"0.5 KM",
),
),
Flexible(
child: new Text(
"\$12.88",
),
),
Flexible(
child: new Text(
"ATM",
),
),
],
),
),
)
],
),
),
Container(
padding: EdgeInsets.all(10),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
height: 50.0,
child: Row (
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo 3",
),
),
Flexible(
child: new Text(
"Lockhart Rd",
),
),
Flexible(
child: new Text(
"1.2 KM",
),
),
Flexible(
child: new Text(
"\$12.88",
),
),
Flexible(
child: new Text(
"Toilet",
),
),
],
),
),
)
],
),
),
Container(
padding: EdgeInsets.all(10),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
height: 50.0,
child: Row (
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo 4",
),
),
Flexible(
child: new Text(
"Canal Rd",
),
),
Flexible(
child: new Text(
"1.2 KM",
),
),
Flexible(
child: new Text(
"\$12.90",
),
),
Flexible(
child: new Text(
"Restaurant, Toilet",
),
),
],
),
),
)
],
),
),
],
),
),
);
}
}
And this is the result:
My questions are:
How to put horizontal gap between cells?
How to reduce the gap between rows?
This is how I'd do it.
ServicePetrolPage
class ServicePetrolPage extends StatefulWidget {
#override
_ServicePetrolPage createState() => _ServicePetrolPage();
}
class _ServicePetrolPage extends State<ServicePetrolPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Petrol'),
),
body: Container(
child: ListView(
children: <Widget>[
DataView(
distance: 'Distance',
facilities: ['Facilities'],
location: 'Location',
logo: ' Logo ',
price: '',
),
DataView(
logo: 'Logo 1',
location: 'Johnson Rd',
distance: '0.2 KM',
facilities: ['ATM', 'Restaurant'],
price: '12.45',
),
DataView(
logo: 'Logo 2',
location: 'Hennessy Rd',
distance: '0.5 KM',
facilities: ['ATM'],
price: '12.88',
),
DataView(
logo: 'Logo 3',
location: 'Lockhart Rd',
distance: '1.5 KM',
facilities: ['Toilet'],
price: '12.88',
),
DataView(
logo: 'Logo 4',
location: 'Canal Rd',
distance: '1.2 KM',
facilities: ['Restaurant', 'Toilet'],
price: '12.90',
),
],
),
),
);
}
}
DataView
class DataView extends StatelessWidget {
final String logo;
final String location;
final String distance;
final String price;
final List<String> facilities;
DataView({
this.location,
this.distance,
this.facilities,
this.logo,
this.price,
});
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("$logo"),
Expanded(
flex: 2,
child: Center(child: Text("$location")),
),
Expanded(
flex: 1,
child: Center(child: Text("$distance")),
),
Expanded(
flex: 1,
child: Center(child: Text("\$$price")),
),
Expanded(
flex: 1,
child: Wrap(
alignment: WrapAlignment.center,
children: <Widget>[
if (facilities != null)
...facilities.map((facility) {
return Padding(
padding: const EdgeInsets.all(0.0),
child: Text(
'$facility ',
overflow: TextOverflow.ellipsis,
),
);
}).toList(),
],
),
),
],
),
);
}
}
Since I am using List unwrapping syntax you will have to update your
SDK constraints in pubspec.yaml
pubspec.yaml
.
.
environment:
sdk: ">=2.2.2 <3.0.0"
1- Add a Container and set the height to 1 with a color you want (between each container row).
Container(
height: 1,
color: Colors.black,
),
2- Reduce the padding, I will change this padding: EdgeInsets.all(10) to this padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2)
Final code:
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text('Petrol'),
),
body: Container(
child: ListView(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
height: 50.0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo",
),
),
Flexible(
child: new Text(
"Location",
),
),
Flexible(
child: new Text(
"Distance",
),
),
Flexible(
child: new Text(
"\$",
),
),
Flexible(
child: new Text(
"Facilities",
),
),
],
),
),
)
],
),
),
Container(
height: 1,
color: Colors.black,
),
Container(
padding: EdgeInsets.all(10),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding:
EdgeInsets.symmetric(horizontal: 10, vertical: 2),
height: 50.0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo 1",
),
),
Flexible(
child: new Text(
"Johnson Rd",
),
),
Flexible(
child: new Text(
"0.2 KM",
),
),
Flexible(
child: new Text(
"\$12.45",
),
),
Flexible(
child: new Text(
"ATM, Restaurant",
),
),
],
),
),
)
],
),
),
Container(
height: 1,
color: Colors.black,
),
Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
height: 50.0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo 2",
),
),
Flexible(
child: new Text(
"Hennessy Rd",
),
),
Flexible(
child: new Text(
"0.5 KM",
),
),
Flexible(
child: new Text(
"\$12.88",
),
),
Flexible(
child: new Text(
"ATM",
),
),
],
),
),
)
],
),
),
Container(
height: 1,
color: Colors.black,
),
Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
height: 50.0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo 3",
),
),
Flexible(
child: new Text(
"Lockhart Rd",
),
),
Flexible(
child: new Text(
"1.2 KM",
),
),
Flexible(
child: new Text(
"\$12.88",
),
),
Flexible(
child: new Text(
"Toilet",
),
),
],
),
),
)
],
),
),
Container(
height: 1,
color: Colors.black,
),
Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
child: Row(
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
height: 50.0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: new Text(
"Logo 4",
),
),
Flexible(
child: new Text(
"Canal Rd",
),
),
Flexible(
child: new Text(
"1.2 KM",
),
),
Flexible(
child: new Text(
"\$12.90",
),
),
Flexible(
child: new Text(
"Restaurant, Toilet",
),
),
],
),
),
)
],
),
),
Container(
height: 1,
color: Colors.black,
),
],
),
),
);
}
I was trying to recreate a design concept from this guy(https://dribbble.com/shots/3812962-iPhone-X-Todo-Concept) but I'm getting some troubles with the ListView alignment or so I think.
What I'm trying to do is moving the List to the right without cutting the edges of the cards when I swipe.
I already tried with margin and padding but none of this applied to the container produces the results I want to obtain.Edges are cutted off when I swipe.
I leave here the Container with the ListView inside it.
Screenshoots of the actual app:
https://imgur.com/a/hJ96sEv
Container(
height: 350.0,
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: 3,
controller: scrollController,
scrollDirection: Axis.horizontal,
itemBuilder: (context, position) {
return GestureDetector(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: Container(
width: 250.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Icon(
cardsList[position].icon,
color: appColors[position],
),
Icon(
Icons.more_vert,
color: Colors.grey,
)
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0, vertical: 4.0),
child: Text(
"${cardsList[position].tasksRemaining} Tasks",
style:
TextStyle(color: Colors.grey),
),
),
Padding(
padding:
const EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 4.0),
child: Text(
"${cardsList[position].cardTitle}",
style:
TextStyle(fontSize: 28.0),
)),
Padding(
padding: const EdgeInsets.all(8.0),
child: LinearProgressIndicator(
value: cardsList[position]
.taskCompletion,
),
)
],
),
),
],
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
),
),
onHorizontalDragEnd: (details) {
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 450));
curvedAnimation = CurvedAnimation(
parent: animationController,
curve: Curves.fastOutSlowIn);
animationController.addListener(() {
setState(() {
currentColor =
colorTween.evaluate(curvedAnimation);
});
});
if (details.velocity.pixelsPerSecond.dx > 0) {
if (cardIndex > 0) {
cardIndex--;
colorTween = ColorTween(
begin: currentColor,
end: appColors[cardIndex]);
}
} else {
if (cardIndex < 2) {
cardIndex++;
colorTween = ColorTween(
begin: currentColor,
end: appColors[cardIndex]);
}
}
setState(() {
scrollController.animateTo((cardIndex) * 256.0,
duration: Duration(milliseconds: 450),
curve: Curves.fastOutSlowIn);
});
colorTween.animate(curvedAnimation);
animationController.forward();
});
},
),
),
What I'm trying to do is moving the List to the right without cutting the edges of the cards when I swipe.
To achieve that goal you need a PageView instead of a ListView, that way you can swipe and "snap" the views when you reach and specific position:
PageView.builder(
itemCount: tasks.length,
controller: PageController(initialPage: 0, viewportFraction: 0.8),
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
child: Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Color(0x40000000),
blurRadius: 10,
offset: Offset(0, 12),
),
],
),
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10),
),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(15),
child: Column(
children: <Widget>[
IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Icon(tasks[index].icon),
Expanded(
child: Container(
child: Align(
alignment: Alignment.topRight,
child: Icon(Icons.menu),
),
),
),
],
),
),
Expanded(
child: Container(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
"${tasks[index].tasks} tasks",
style: TextStyle(
color: Color(0xD0000000),
fontSize: 15,
),
),
SizedBox(height: 10),
Text(
"${tasks[index].title}",
style: TextStyle(
color: Color(0xD0000000),
fontSize: 24,
),
),
SizedBox(height: 10),
LinearProgressIndicator(
value: tasks[index].percentage,
backgroundColor: Color(0x300000FF),
)
],
),
),
),
],
),
),
),
),
);
},
)
The result of this implementation is something like this:
If you want to change the offset of the cards, you need to modify the value viewportFraction: 0.8 to anything you'd like. 1.0 is the value without offset.
You can find my full implementation over this Gist Github