Vertical dotted Line between two or multiple points in Flutter - flutter

I need a lil help to draw dotted line between 2 points without using google map's poly lines.
I tried with canvas, it does but not exactly start under and above location.
Right now you can see 2 points later it'll be more than 2 points.
It really appreciated if anyone help me to achieve.

I think drawing is more efficient than creating more containers like the one above. If you don't want to use the library, you can use my following method, simply adding a few lines:
Create class DashedLineVerticalPainter:
class DashedLineVerticalPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
double dashHeight = 5, dashSpace = 3, startY = 0;
final paint = Paint()
..color = Colors.grey[300]
..strokeWidth = size.width;
while (startY < size.height) {
canvas.drawLine(Offset(0, startY), Offset(0, startY + dashHeight), paint);
startY += dashHeight + dashSpace;
}
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
And use it:
CustomPaint(
size: Size(1, double.infinity),
painter: DashedLineVerticalPainter()
)
Result:

I have made almost same looking widget by using https://pub.dev/packages/flutter_dash, you can also customise this widget according to your style.
Here is the code,Hope it helps.
Column(children: <Widget>[
Container(
margin: EdgeInsets.only(top: 16),
height: 25,
width: 25,
decoration: BoxDecoration(
shape: BoxShape.circle,
border:
Border.all(width: 1.5, color: Colors.greenAccent)),
),
Dash(
direction: Axis.vertical,
length: 130,
dashLength: 15,
dashColor: grey),
Container(
height: 25,
width: 25,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
border: Border.all(width: 2, color: red)),
child: Container(
height: 20,
),
),
],
),

class _MyWidgetState extends State<MyWidget> {
List<Model> list = [];
#override
void initState() {
super.initState();
list.add(Model("Hyderabad", Colors.red));
list.add(Model("Visakhapatnam", Colors.green));
list.add(Model("Vijayawada", Colors.blue));
}
void addNew() {
setState(() {
list.add(Model("Karnool", Colors.black));
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
title:
Text('Custom Stepper', style: TextStyle(color: Colors.white)),
actions: [
IconButton(
icon: Icon(Icons.add_circle, color: Colors.white),
onPressed: addNew)
]),
body: Container(
padding: EdgeInsets.all(15),
color: Colors.white,
child: ListView.builder(
itemCount: list.length,
itemBuilder: (con, ind) {
return ind != 0
? Column(mainAxisSize: MainAxisSize.min, children: [
Row(children: [
Column(
children: List.generate(
3,
(ii) => Padding(
padding: EdgeInsets.only(
left: 10, right: 10, top: 5, bottom: 5),
child: Container(
height: 3,
width: 2,
color: Colors.grey,
)),
),
),
Expanded(
child: Container(
color: Colors.grey.withAlpha(60),
height: 0.5,
padding: EdgeInsets.only(
left: 10,
right: 20,
),
))
]),
Row(children: [
Icon(Icons.location_on, color: list[ind].color),
Text(list[ind].address,
style: TextStyle(color: list[ind].color))
])
])
: Row(children: [
Icon(Icons.location_on, color: list[ind].color),
Text(list[ind].address,
style: TextStyle(color: list[ind].color))
]);
})));
}
}
class Model {
String address;
double lat;
double long;
Color color;
//Other fields if needed....
Model(this.address, this.color);
//initialise other fields so on....
}

return Container(
child: Row(
children: <Widget>[
Column(children: <Widget>[
Icon(Icons.radio_button_checked,color: Colors.orange,)
Dash(
direction: Axis.vertical,
length: 20,
dashLength: 5,
thickness:3.0,
dashColor: Colors.grey[400]),
Icon(Icons.location_on,color: Colors.blue,)
],
),
Column(children: <Widget>[
Text("Some text"),
Divider(),
Text("Some Text")
],
),
],
)
);

Related

Need help to build custom widget in flutter

Hey I try to create a custom widget like this, where I can change the text in the bottom part of the card.
I already create the shape but I have no idea on how to place Text('Aktif'), I tried using Stack or Column but none works, any Idea?
Here is my code:
#override
Widget build(BuildContext context) {
return Stack(
children: [
Card(
shape: CardShape(),
elevation: 18,
shadowColor: const Color.fromRGBO(51, 0, 0, 0.1),
color: CustomStyle.primaryRed,
child: Container(
decoration: BoxDecoration(
color: CustomStyle.white,
border: Border.all(color: CustomStyle.primaryRed),
borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.symmetric(vertical: 8),
child: ListTile(
title: const Text('Rumah Tanggerang'),
subtitle: const Text('Primary - 1234567890'),
trailing: Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'DEFAULT',
),
myPopMenu()
],
),
),
),
),
Positioned(left: 10, bottom: 0, child: Text('Aktif'))
],
);
}
class CardShape extends ShapeBorder {
const CardShape();
final BorderSide _side = BorderSide.none;
final BorderRadiusGeometry _borderRadius = BorderRadius.zero;
#override
EdgeInsetsGeometry get dimensions => EdgeInsets.all(_side.width);
#override
Path getInnerPath(
Rect rect, {
TextDirection? textDirection,
}) {
final Path path = Path();
path.addRRect(
_borderRadius.resolve(textDirection).toRRect(rect).deflate(_side.width),
);
return path;
}
#override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
final Path path = Path();
final RRect rrect = _borderRadius.resolve(textDirection).toRRect(rect);
path.moveTo(0, 10);
path.quadraticBezierTo(0, 0, 10, 0);
path.lineTo(rrect.width - 10, 0);
path.quadraticBezierTo(rrect.width, 0, rrect.width, 10);
path.lineTo(rrect.width, rrect.height - 10);
path.quadraticBezierTo(
rrect.width, rrect.height, rrect.width - 10, rrect.height);
path.lineTo(100, rrect.height);
path.lineTo(80, rrect.height + 20);
path.lineTo(10, rrect.height + 20);
path.quadraticBezierTo(0, rrect.height + 20, 0, rrect.height + 10);
return path;
}
#override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}
#override
ShapeBorder scale(double t) => RoundedRectangleBorder(
side: _side.scale(t),
borderRadius: _borderRadius * t,
);
}
Card widget can't used stack because the red container is already outside the Card element so to put the text you just can wrap Stack inside of a Column and put the Text widget without position this is the example that I've already did
class Test extends StatelessWidget {
const Test({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
decoration: const BoxDecoration(color: Colors.blue),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
Card(
shape: const CardShape(),
elevation: 18,
shadowColor: const Color.fromRGBO(51, 0, 0, 0.1),
color: Colors.red,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.red),
borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.symmetric(vertical: 8),
child: ListTile(
title: const Text('Rumah Tanggerang'),
subtitle: const Text('Primary - 1234567890'),
trailing: Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: const <Widget>[
Text(
'DEFAULT',
),
],
),
),
),
),
],
),
const Padding(
padding: EdgeInsets.only(
left: 30,
),
child: Text(
'Aktif',
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.w700),
),
)
],
),
),
),
);
}
}
if you copy my code just made sure to change back the color you've used.

How to make Flutter GridView change colors when tapped

I have asked this question previously but I am not receiving much help. I've created a GridView using GridView.count; however, I cannot get an indiviual container to change colors. The entire row changes if I click on any container within the row. I want to be able to change an individual container's color when it is tapped on, as well as have check mark appear on the top right corner of the container when selected.
(1) My Layout
(2) An Example of what I would like to happen
I'm very new to Flutter, so my code is not very optimal. I've tried making a list model as well but I have not had any luck with that. I'm attaching a portion of my code to show what I've done so far. Any help would be great :)
Widget build(BuildContext) {
double _height = MediaQuery.of(context).size.height;
final data = ModalRoute.of(context)!.settings;
String retrieveString;
if (data.arguments == null) {
retrieveString = "empty";
} else {
retrieveString = data.arguments as String;
}
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: const Color(0xff31708c),
body: Padding(
padding: EdgeInsets.only(
left: 30,
right: 30,
top: _height * 0.2),
child: Column(
children: <Widget>[
Text('Hi $retrieveString! What all would you like to focus on?',
style: GoogleFonts.montserrat(
color: Colors.white70,
fontSize: 19,
fontWeight: FontWeight.w600
),
textAlign: TextAlign.center,),
const SizedBox(height: 9),
Text("You can pick all that apply:",
style: GoogleFonts.montserrat(
color: Colors.white70,
fontSize: 14.5,
fontWeight: FontWeight.w600
),),
const SizedBox(height: 9,),
Column(children: [
GridView.count(
primary: true,
shrinkWrap: true,
padding: const EdgeInsets.all(10),
childAspectRatio: 1.15,
crossAxisCount: 2,
crossAxisSpacing: 25,
mainAxisSpacing: 25,
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
_ContainerColor = _ContainerColor == Colors.white
? Color(0xffa1d0e6)
: Colors.white;
});
},
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: const Color.fromARGB(255, 20, 83, 106),
width: 2.5),
color: _ContainerColor
),
child: Column(
children: [
const Align(alignment: Alignment.topCenter,
child: Icon(MyFlutterApp.relationships,
color: Color(0xff31708c),
size: 45,),
),
const SizedBox(height: 4,),
Text('Maintaining healthy relationships',
style: GoogleFonts.montserrat(
fontSize: 14,
fontWeight: FontWeight.w500,
color: const Color(0xff31708c)
),
textAlign: TextAlign.center,)
],
),
),
),
From my understanding, you have to do allow users to have multi-select, because of the line
You can pick all that apply:
So here is a custom stateful widget that helps you to do multi-select, you can have your own widget child inside the gridview.
class CustomPage extends StatefulWidget {
const CustomPage({Key? key}) : super(key: key);
#override
State<CustomPage> createState() => _CustomPageState();
}
class _CustomPageState extends State<CustomPage> {
String retrieveString = "";
List selectedIndex = [];
List dataItems = ['India', 'USA', 'Germany'];
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
final data = ModalRoute.of(context)!.settings;
if (data.arguments == null) {
retrieveString = "empty";
} else {
retrieveString = data.arguments as String;
}
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: const Color(0xff31708c),
body: Padding(
padding: EdgeInsets.only(left: 30, right: 30, top: height * 0.2),
child: Column(children: <Widget>[
Text('Hi $retrieveString! What all would you like to focus on?'),
const SizedBox(height: 10),
const Text("You can pick all that apply:"),
const SizedBox(height: 10,),
Expanded(
child: GridView.builder(
scrollDirection: Axis.vertical,
primary: true,
shrinkWrap: true,
padding: const EdgeInsets.all(10),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1.15,
crossAxisCount: 2,
crossAxisSpacing: 25,
mainAxisSpacing: 25),
itemCount: dataItems.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
setState(() {
if (selectedIndex.contains(index)) {
selectedIndex.remove(index);
} else {
selectedIndex.add(index);
}
});
},
child: Stack(
alignment: Alignment.topRight,
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color:
const Color.fromARGB(255, 20, 83, 106),
width: 2.5),
color: selectedIndex.contains(index)
? const Color(0xffa1d0e6)
: Colors.white),
child: Center(
child: Text(dataItems[index]),
),
),
selectedIndex.contains(index)
? Container(
padding: const EdgeInsets.all(10),
child: const CircleAvatar(
child: Icon(Icons.check_outlined),
),
)
: Container()
],
),
);
},
),
)
])));
}
}
Hope it resolves your issue.
I've created your app as a test version. All you need to do is inject your widget in the //put your widget here!!!!! section. Also for testing this right now as a demo, you can paste the code on dartpad and select "New" -> "Flutter" -> Paste Code: https://dartpad.dev
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowtappedModeBanner: false,
home: Scaffold(
body: Center(
child: CustomCheckboxGrid(),
),
),
);
}
}
class CustomCheckboxGrid extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _CustomCheckboxGridState();
}
}
class _CustomCheckboxGridState extends State<CustomCheckboxGrid> {
int tapped_index = 0;
List card_names = [
'Maintaining healthy relationships',
'Being happier and more content in life',
'Work life balance',
'Personal Growth',
'Stress',
'Mental health',
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.builder(
padding: const EdgeInsets.all(16),
itemCount: card_names.length,
itemBuilder: (BuildContext context, int index) {
return buildCard(index);
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
),
);
}
Widget buildCard(int index) {
bool tapped = index == tapped_index;
String current_name = card_names[index];
return GestureDetector(
onTap: () {
setState(() {
print("Tapped index: ${index}");
tapped_index = index;
});
},
child: Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(14),
child:
//put your widget here!!!!!
//-----------------------------------
Card(
color: tapped ? Colors.orange : Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Container(
child: Center(child: Text(current_name)),
),
),
//-----------------------------------
),
Positioned(
top: 14,
right: 14,
child: Offstage(
offstage: !tapped,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 2),
shape: BoxShape.circle),
child: Icon(
Icons.check,
color: Colors.green,
),
),
),
),
],
),
);
}
}

Flutter : Use function from another file in widget

I'm using flutter and i'm completely a newbie with this framework. I'm trying to use the visibility widget to show and hide a Row.
I'm trying to use this widget when I declare the variable bool _isVisible = false in a stateful or stateless widget, but I have a problem when I want to show and hide the row() through a widget from another dart file. I don't know how to do it. To solve this problem i'm trying to create a dart file for create a function and variable bool _isVisible = false; so that all widgets can access but I am unable to use the bool variable and the function of this dart file in my widgets.
in this picture: ontap in the green circle i want the pink color all the row() with the rating and the button to be hidden.
A screenshot of the issue from my application
P.S: sorry for my english
This is the widget( AnimeMovieDialog ) with the rating section that i want to be hidden (or show) when user tap on the CardAnimeMovie widget.
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Tutorial by Woolha.com',
home: AnimeMovieDialog(),
debugShowCheckedModeBanner: false,
);
}
}
class AnimeMovieDialog extends StatefulWidget {
#override
_AnimeMovieDialogState createState() => _AnimeMovieDialogState();
}
class _AnimeMovieDialogState extends State<AnimeMovieDialog> {
double _rating = 1;
double count = 1;
bool _isVisible = true;
void _change() {
setState(() {
_isVisible = !_isVisible;
print("tap succes");
});
}
void _close() {
setState(() {
_isVisible = false;
});
}
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return SafeArea(
child: Visibility(
visible: _isVisible,
child: Stack(children: [
Container(
width: width,
height: height,
decoration: BoxDecoration(color: Color(0xffffff).withOpacity(0.6)),
),
Center(
child: SingleChildScrollView(
child: Container(
width: width / 1.05,
height: height / 1.2,
decoration: BoxDecoration(color: Color(0xff212529)),
child: Column(
children: [
Row(
children: [
Container(
width: width / 1.05,
height: 60,
decoration: BoxDecoration(color: Color(0xff212529)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding:
const EdgeInsets.fromLTRB(4.0, 5, 35, 0),
child: GestureDetector(
onTap: () {
_close();
},
child: Container(
width: 65,
height: 45,
color: Colors.blue,
child: Icon(Icons.clear,
color: Colors.white)),
),
),
Container(
width: width / 2,
height: height / 2,
child: TextField(
cursorColor: Colors.orange,
style: TextStyle(
color: Colors.white,
),
maxLines: 1,
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.white)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.orange)),
border: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.white)),
hintText: 'Rechercher',
hintStyle:
TextStyle(color: Colors.white),
)),
),
Padding(
padding:
const EdgeInsets.fromLTRB(15, 0, 8, 0),
child: Container(
child: Icon(Icons.search,
color: Colors.white)),
)
],
),
)
],
),
Row(
children: [
Container(
width: width / 1.05,
height: height / 1.5,
child: ListView(
children: [
CardAnimeMovie(),
CardAnimeMovie(),
CardAnimeMovie(),
CardAnimeMovie(),
CardAnimeMovie(),
CardAnimeMovie()
],
),
)
],
),
Row(children: [
Column(
children: [
Container(
width: width / 2,
height: height / 11.25,
color: null,
child: Row(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(
25, 0, 0, 0),
child: GFRating(
onChanged: (value) {
setState(() {
_rating = value;
});
},
value: _rating,
size: 25,
color: Colors.orange,
borderColor: Colors.orange,
),
)
],
)),
],
),
Padding(
padding: const EdgeInsets.fromLTRB(35, 0, 8, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: width / 3,
height: height / 18,
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25.0),
topRight: Radius.circular(25.0),
bottomLeft: Radius.circular(25.0),
bottomRight: Radius.circular(25.0))),
child: TextButton(
style: TextButton.styleFrom(
primary: Colors.blue,
onSurface: Colors.red,
),
onPressed: null,
child: Text('Noter',
style: TextStyle(
color: Colors.white,
fontFamily: 'DBIcons',
fontSize: 17)),
),
),
],
),
)
])
],
)),
),
),
]),
),
);
}
}
This is the movie resume (green in the picture)
class CardAnimeMovie extends StatefulWidget {
#override
_CardAnimeMovieState createState() => _CardAnimeMovieState();
}
class _CardAnimeMovieState extends State<CardAnimeMovie> {
// bool _visible = false;
// void ratechange() {
// setState(() {
// _visible = !_visible;
// });
// }
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return Padding(
padding: const EdgeInsets.all(2.0),
child: GestureDetector(
onTap: () {
ratechange();
},
child: Container(
width: width / 5,
height: height / 3.2,
decoration: BoxDecoration(color: Color(0xff272824)),
child: Row(
children: [
Column(children: [
Container(
width: width / 2.1,
height: height / 3.2,
child: Image.network(
'https://image.noelshack.com/fichiers/2014/31/1406628082-btlbdfqiyaasamj.jpg',
fit: BoxFit.cover,
),
)
]),
Column(children: [
Container(
width: width / 2.15,
height: height / 3.2,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.white, width: 0.5),
),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(15, 5, 0, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Text(
'Titre : oeuvre',
style: TextStyle(
color: Colors.white,
fontFamily: 'DBIcons',
fontSize: 18,
),
)
],
),
SizedBox(
height: 0.5,
),
Row(
children: [
Text(
'Auteur : XXXX',
style: TextStyle(
color: Colors.white,
fontFamily: 'DBIcons',
fontSize: 18,
),
)
],
),
SizedBox(height: 7),
Row(
children: [
Container(
width: width / 2.5,
height: height / 5,
child: Text(
"RĂ©sume : Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries,",
style: TextStyle(
color: Colors.white,
fontFamily: 'DBIcons',
fontSize: 18,
),
),
)
],
)
],
),
),
)
])
],
)),
),
);
}
}
You can give function to another dart file and with this you can invoke function in another dart file.
For example:
class AnotherWidget extends StatelessWidget{
final Function myFunction;
AnotherWidget ({this.myFunction});
#override
Widget build(BuildContext context) {
return FlatButton(onPressed: myFunction,....);
}

how to make this table scrollable to bottom

i am beginner in flutter , i wrote a code with a leagueboard table from api , after i executed i found that my table is not scrolling , the scroll appears only on the top but no scrolling to bottom
here what i have tried:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:http/http.dart' as http;
class LeagueBoard extends StatefulWidget {
#override
_LeagueBoardState createState() => _LeagueBoardState();
}
class _LeagueBoardState extends State<LeagueBoard> {
List<Club> clubs = [];
getTable() async {
http.Response response = await http.get(
'http://api.football-data.org/v2/competitions/PL/standings',
headers: {'X-Auth-Token': '86014f6025ae430dba078acc94bb2647'});
String body = response.body;
Map data = jsonDecode(body);
List table = data['standings'][0]['table'];
// for (var team in table) {
// clubs.add(Club(team['team']['crestUrl'].toString(), team['position'].toString(),team['points'].toString(),team['points'].toString(),team['playedGames'].toString(),team['won'].toString(),
// team['draw'].toString(),team['lost'].toString(),team['goalsFor'],team['goalsAgainst']));
// print(team);
// }
// for (var team in table) {
// clubs.add(Club(team['team']['crestUrl'].toString(), team['position'].toString(),team['points'].toString(),team['points'].toString(),team['playedGames'].toString(),team['won'].toString(),
// team['draw'].toString(),team['lost'].toString(),team['goalsFor'],team['goalsAgainst']));
// print(team);
// }
// for (var team in clubs) {
// debugPrint(team.toString());
// }
setState(() {
for (var team in table) {
clubs.add(Club(team['team']['name'],team['team']['crestUrl'], team['position'].toString(),team['points'].toString(),team['playedGames'].toString(),team['won'].toString(),
team['draw'].toString(),team['lost'].toString(),team['goalsFor'],team['goalsAgainst']));
print("hello");
}
});
}
// List<Club> clubs = [ Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),];
#override
void initState() {
super.initState();
getTable();
}
#override
Widget build(BuildContext context) {
return clubs == null
? Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Color(0xFFe70066),
),
),
),
)
: Scaffold(
appBar: AppBar(
title: Text("LeagueBoard"),
backgroundColor: Colors.blue[300],
elevation: 0.0,
),
body: SingleChildScrollView(
child: Column(
children: [
TopRow(),
ListView.builder(
shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
itemCount: clubs.length,
itemBuilder: (context, index) {
return TableRow(index: index, clubs:clubs);
},
),
],
),
),
);
}
}
class TopRow extends StatelessWidget {
const TopRow({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
TextStyle textStyle = TextStyle(fontSize: 11, fontWeight: FontWeight.bold);
TextStyle textStyle2 = TextStyle(fontSize: 13);
return Container(
child: Row(
children: [
Container(
alignment: Alignment.center,
width: 30,
height: 30,
child: Text('#'),
),
SizedBox(width: 20),
Container(alignment: Alignment.center, child: Text('Team')),
Spacer(),
Container(
width: 28,
child: Text('MP', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('W', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('D', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('L', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('GD', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('Pts', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 5,
height: 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.grey[800],
),
padding: EdgeInsets.fromLTRB(10, 5, 2, 5),
),
],
),
);
}
}
class TableRow extends StatelessWidget {
final int index;
final List<Club> clubs;
const TableRow({
this.index,
this.clubs,
Key key,
}) : super(key: key);
/////////////////////////////////////////////////////////////////////linkwell
////////////////////////////////////////////////////////////////////
#override
Widget build(BuildContext context) {
TextStyle textStyle = TextStyle(fontSize: 11, fontWeight: FontWeight.bold);
TextStyle textStyle2 = TextStyle(fontSize: 13, fontWeight: FontWeight.bold);
return Container(
width: double.infinity,
height: 40,
decoration: BoxDecoration(
border: Border.all(color: Colors.black38, width: 0.2),
color: index == 0 ? Colors.yellow[100] : Colors.purpleAccent[20],
),
child: Row(
children: [
Container(//iinkwell
alignment: Alignment.center,
width: 30,
height: 40,
color: index < 2
? Colors.blue
: index == 2
? Colors.red[400]
: index > 11
? Colors.red[800]
: Colors.grey[700],
child: Text(
(index + 1).toString(),
style: TextStyle(color: Colors.white),
),
),
SizedBox(width: 20),
Row(children: [
SvgPicture.network(clubs[index].image,
width: 24.0, height: 24.0,
),
SizedBox(width: 5.0),
clubs[index].name.length > 11
? Text(clubs[index].name
.toString()
.substring(0, 11) +
'...')
: Text(clubs[index].name.toString(), style: textStyle2),
],),
Spacer(),
Container(
width: 28,
child: Text(clubs[index].matches, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text(clubs[index].wins, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text(clubs[index].draws, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text(clubs[index].loss, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text((clubs[index].goals - clubs[index].goalsIn).toString(), style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text(clubs[index].points, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 5,
height: 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.grey[600],
),
padding: EdgeInsets.fromLTRB(10, 5, 2, 5),
),
],
),
);
}
}
class Club {
String name;
String image;
String rank;
String points;
String matches;
String wins;
String loss;
String draws;
int goals;
int goalsIn;
Club(this.name,this.image,this.rank,this.points, this.matches,this.wins,this.loss,this.draws,this.goals,this.goalsIn);
}
I am trying to make my table scrolling because i can not see all of the teams that came from becand due to non scrolling reasons
You are using ListView inside SingleChildScrollView. So set that ListView as non-primary.
primary: false
Change at this point in your code
ListView.builder(
shrinkWrap: true,
primary: false,
// physics: NeverScrollableScrollPhysics(),
itemCount: clubs.length,
itemBuilder: (context, index) {
return TableRow(index: index, clubs:clubs);
},
),

Buttons center their children when they are placed in a ListView.builder widget

Why do buttons in Flutter tend to align their children to the centre when they are placed in list views?
For example:
import 'package:flutter/material.dart';
class Test extends StatefulWidget {
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: 10,
itemBuilder: (context, index){
return MaterialButton(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Hello"),
],
));
}
),
);
}
}
This would result in ten hellos spaced evenly by the default height of the button, but they would be centered; even though I used the CrossAxisAlignment.start property in a column.
Here is the image:
But when I replace the MaterialButton with a Container they are aligned to the start to the column as wanted.
When I just remove the ListView.Builder I get 'hello' aligned to the start.
The same thing happens with the rest of the buttons.
Is there a way to make buttons in list views not have centered children inside them?
Edit: the example was fixed by #Harry but it didn't fix my exact code
here is my code: I try to created a list of widgets outside and use a function to add my list items into that list and return a list view through the ActivitiesList widget
import 'package:flutter/material.dart';
import 'package:list_them_out/models/activities.dart';
import 'package:provider/provider.dart';
class ActivitiesList extends StatefulWidget {
#override
_ActivitiesListState createState() => _ActivitiesListState();
}
double conBorderRadius = 30;
class _ActivitiesListState extends State<ActivitiesList> {
List<Widget> itemData = [];
void getData(context) {
double cardHeight = MediaQuery.of(context).size.height * 0.3;
double cardWidth = MediaQuery.of(context).size.width * 0.97;
final activities = Provider.of<List<Activity>>(context);
activities == null
// ignore: unnecessary_statements
? null
: setState(() {
itemData = [];
});
activities == null
// ignore: unnecessary_statements
? null
: setState(() {
activities.forEach((element) {
itemData.add(Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Container(
width: cardWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(conBorderRadius),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: <Color>[
Colors.lightGreen[300],
Colors.lightBlue[300],
]
),
boxShadow: [
BoxShadow(
color: Colors.grey[600],
offset: Offset(4.0, 4.0),
blurRadius: 15,
spreadRadius: 1),
BoxShadow(
color: Colors.white,
offset: Offset(-4.0, -4.0),
blurRadius: 15,
spreadRadius: 1),
]),
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(conBorderRadius),
child: MaterialButton(
splashColor: HSLColor.fromColor(Colors.green).toColor(),
onPressed: () {},
child: Align(
alignment: Alignment.centerLeft,
child: Container(
child: Padding(
padding: EdgeInsets.only(top: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: cardWidth * 0.61,
child: Text(
element.name,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.grey[600],
fontSize: 25,
fontWeight: FontWeight.w500,
letterSpacing: 1,
),
),
),
Padding(
padding: EdgeInsets.only(top: cardHeight * 0.09, left: cardWidth * 0.03),
child: Container(
width: cardWidth * 0.48,
child: RichText(
maxLines: 2,
overflow: TextOverflow.ellipsis,
text: TextSpan(children: [
TextSpan(
text: "Start: ",
style: TextStyle(
color: Colors.grey[800],
fontSize: 20,
fontWeight: FontWeight.w400,
letterSpacing: 1),
),
TextSpan(
text: element.time,
style: TextStyle(
color: Colors.black87,
fontWeight: FontWeight.w300,
fontSize: 20,
))
]),
),
),
),
SizedBox(height: cardHeight * 0.06,),
Row(
children: [
IconButton(icon: Icon(Icons.comment),
onPressed: () => null,
color: Colors.grey[600],
),
Padding(
padding: EdgeInsets.only(bottom: 5),
child: Text("Comments", style: TextStyle(color: Colors.grey[600], fontSize: 20, fontWeight: FontWeight.w300, letterSpacing: 1),),
)
],
)
],
),
),),
),
),
),
Positioned(
right: 0,
bottom: 0,
top: 0,
child: ClipPath(
clipper: MyClip(radius: conBorderRadius),
child: Container(
height: cardHeight,
width: cardWidth * 0.45,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: <Color>[
Colors.grey[300],
Colors.lightBlue[100].withOpacity(0.5)
])),
),
),
),
Positioned(
right: cardWidth * 0.05,
bottom: 20,
child: Container(
child: Text("Hello"),
),
)
],
)),
));
});
});
}
#override
Widget build(BuildContext context) {
double listHeight = MediaQuery.of(context).size.height * 0.86;
double listWidth = MediaQuery.of(context).size.width * 0.97;
getData(context);
return ClipRRect(
borderRadius: BorderRadius.only(
topRight: Radius.circular(50), topLeft: Radius.circular(50)),
child: Container(
height: listHeight,
width: listWidth,
child: ListView.builder(
itemCount: itemData.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(bottom: 30),
child: itemData[index],
);
}),
));
}
}
``
Try using the Align widget. Just wrap the column with an align widget and have the alignment parameter be alignment.centerLeft.
import 'package:flutter/material.dart';
class Test extends StatefulWidget {
#override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: 10,
itemBuilder: (context, index){
return MaterialButton(
child: Align(
child:Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Hello"),
],
),
alignment: Alignment.centerLeft,
)
);
}
),
);
}
}