Set text to match column width in flutter - dart

I have an image and a text in a column.
I want the text container to expand to the column width, creating a black border with the text centered.
This is what i got now.
Code.
List<Container> getMediaItem(List<Media> mediaItems) {
List<Container> mediaContainers = [];
for (Media media in mediaItems) {
mediaContainers.add(
Container(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
media.image,
Container(
color: Colors.black,
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Text(media.title),
)
],
),
),
);
}
return mediaContainers;
}
If you know how to solve it please share.
Update:
The full code (I'm trying to make a nested scroll view to display a gallery of media items, like Netflix):
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Live Tree',
theme: ThemeData(
brightness: Brightness.dark,
),
home: Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text("LiveTree"),
Icon(Icons.check_circle_outline),
],
),
),
body: HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
List<Column> getMediaItem(List<Media> mediaItems) {
List<Column> mediaContainers = [];
for (Media media in mediaItems) {
mediaContainers.add(
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
media.image,
Container(
color: Colors.black,
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Text(media.title),
)
],
),
);
}
return mediaContainers;
}
List<Widget> getCategoryRows(List<CategoryModel> categoryModels) {
List<Widget> categoryRows = [];
for (CategoryModel category in categoryModels) {
final mediaItemsForCategory = getMediaItem(category.media);
categoryRows.add(
ListView(scrollDirection: Axis.horizontal,
children: mediaItemsForCategory,
),
);
}
return categoryRows;
}
Widget gallerySection = Column(
mainAxisSize: MainAxisSize.min,
children: getCategoryRows(mockCategoryDataSet),
);
return Scaffold(
body: ListView(
children: <Widget>[
gallerySection,
],
),
);
}

Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
media.image,
Container(
color: Colors.black,
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Text(media.title),
),
],
);
or
Column(
children: [
media.image,
Container(
color: Colors.black,
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Center(
child: Text(media.title),
),
),
],
);

Related

Passing dates(variables) between Classes?

I need to pass variables between classes.
for example:
archive ClassN1.dart
The Class N1 content variable1 = 0
archive ClassN2.dart
the class N2 calculate sumVariables = Variable1 * 2;
For days I've been looking for information about it.
From already thank you very much!
import 'package:flutter/material.dart';
import 'Funtion_Calculate.dart';
class DatesPrincipal extends StatelessWidget {
get left => null;
#override
Widget build(BuildContext context) {
return new Container(
child: Row(
children: <Widget>[
new Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[ //First linea of dates
NumberDates(),
StatusNPS(),
PutDatesNPS()
],
),
)
],
),
);
}
}
class NumberDates extends StatefulWidget {
#override
_NumberDatesState createState() => _NumberDatesState();
}
class _NumberDatesState extends State<NumberDates> {
var adecuado = '0';
Widget build(BuildContext context) {
Widget iconList;
return iconList = DefaultTextStyle.merge(
style: descTextStyle,
child: Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
child: Column(
children: <Widget>[
Text(adecuado,
style: TextStyle(
fontSize: 18
),
),
Padding(
padding: EdgeInsets.all(4),
),
Text('Adecuado')
],
),
width: 100.0,
),
],
),
)
);
}
}
The archive number2.dart
- status = adecuado * 2
class StatusNPS extends StatefulWidget {
#override
_StatusNPSState createState() => _StatusNPSState();
}
class _StatusNPSState extends State<StatusNPS> {
var status = '82.9'; // status = adecuado * 2
Widget build(BuildContext context) {
Widget iconList;
return iconList = DefaultTextStyle.merge(
style: descTextStyle,
child: Container(
width: 400.0,
padding: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(status, style: TextStyle(
fontFamily: 'SF Pro',
),),
Text(' %', style: TextStyle(
fontSize: 65.0,
fontFamily:'SF Pro',
),)
],
)
)
);
}
}

flutter scrollview not scrolling

I have this
Widget _Project() {
return new ListView(
children: <Widget>[
Container(
child: Card(
color: _Cardcolor,
child: Center(
child: Text(
'Projects',
style: new TextStyle(
fontSize: 40.0,
),
),
),
),
margin: EdgeInsets.only(left: 50.0, right: 50.0, top: 10.0),
height: 130.0,
width: 15.0,
),
Divider(
height: 40,
),
Container(
child: FutureBuilder<List<Project>>(
future: fetchProjects(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ProjectList(projects: snapshot.data)
: Center(child: CircularProgressIndicator());
},
),
)
],
) ;
}
and this is the builder
class ProjectList extends StatelessWidget {
final List<Project> projects;
ProjectList({Key key, this.projects}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView.builder(
shrinkWrap: true,
itemCount: projects.length,
itemBuilder: (context, index) {
return Column(
children: <Widget>[
Container(
color: Colors.white10,
alignment: Alignment.center,
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text(projects[index].ProjectId),
subtitle: Text(projects[index].ProjectId),
),
ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: ButtonBar(
children: <Widget>[
FlatButton(
child: const Text('Open'),
onPressed: () {/* ... */},
),
],
),
),
],
),
)),
],
);
},
);
}
}
So, i'm creating the list with card. Here is the screenshot
the data is from json and it is showing properly. Well, it is not showing properly because i have 5 and it is only showing 3, well it is because the scrolling problem. When i make the card smaller all of my data is showing up.
I already try to add this line
physics: const AlwaysScrollableScrollPhysics()
But still no help, I'm stuck now
How can i fix it ? did i miss something ?
In Your class - ProjectList() - ListView.builder - add - physics: ClampingScrollPhysics(),
Widget build(BuildContext context) {
return ListView.builder(
physics: ClampingScrollPhysics(), // add this
shrinkWrap: true,
itemCount: projects.length,
itemBuilder: (context, index) {
return Column(
children: <Widget>[ ...
update:
To make the card list scroll only not the whole page - replace top Listview with the column.
return Scaffold(
body: Column( // replace from listview
children: <Widget>[
SizedBox(height: 15.0,),
Container(
child: Card(
// color: _Cardcolor,
child: Text(
'Projects',
style: new TextStyle(
fontSize: 44.0,
),
),
),
margin: EdgeInsets.only(left: 50.0, right: 50.0, top: 15.0),
height: 130.0,
// width: 15.0,
),
Divider(
height: 40,
),
Expanded( // add Expanded
child: Container(
child: ProjectList(
projects: ['anmol', 'anmol', 'dummy', 'demo'],
),
// child: FutureBuilder<List<Project>>(
// future: fetchProjects(http.Client()),
// builder: (context, snapshot) {
// if (snapshot.hasError) print(snapshot.error);
// return snapshot.hasData
// ? ProjectList(projects: snapshot.data)
// : Center(child: CircularProgressIndicator());
// },
// ),
),
)
],
),

flutter Listview itemextent

I'm struggling with the ListView.
My problem is that I've a Listview inside another Listview and the second Listview items height are not always the same. I want to get rid of the itemExtent and create an automatically height for the first Listview.
What I really want to acomplish is something like this:
#override
Widget build(BuildContext context) {
return
Column(
children: <Widget>[
TextField(),
Expanded(
child: ListView.builder(
key: new Key("ditisdekeyvoordelistview"),
itemBuilder: _makeMovieList,
padding: EdgeInsets.all(0.0),
itemCount: _movies.length,
itemExtent: 300.0,
),
),
],
);
}
//FIRST LIST
Widget _makeMovieList(BuildContext context, int index) {
return Container(
child: ListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
leading: Container(
child: Column(mainAxisSize: MainAxisSize.max, children: <Widget>[
Image.network(
_movies[index].movieImage,
fit: BoxFit.cover,
width: 100.0,
)
])),
title: Text(
_movies[index].movieTitle,
),
subtitle: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_makeStarRating(_movies[index].movieRating),
Text(_movies[index].movieDescription),
_makeCardDates(index)
],
),
),
);
}
//SECOND LIST
Widget _makeCardDates(int index) {
return Expanded(
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.all(0.0),
itemCount: _movies[index].dateTimeList.length,
itemBuilder: (context, indexx) {
return GestureDetector(
onTap: () {
print(_movies[index].dateTimeList[indexx].toString());
},
child: Card(
elevation: 8.0,
color: Color.fromRGBO(64, 75, 96, .9),
child: Column(
children: <Widget>[
Text(_movies[index].cinema),
Text(((dateFormatMovieHours
.format(_movies[index].dateTimeList[indexx]))
.toString())),
],
)));
},
itemExtent: 40.0,
),
);
}
Using itemExtent on a ListView isn't required, though ListView needs to have a finite height set for vertical scroll (default) and finite width is needed for horizontal scroll. Otherwise, the ListView will throw a "constraints are unbounded" error.
For your use case, you can either set height on the list items in the first ListView, or set height on the second ListView. However, if you'd like the second ListView to be non-scrollable and the list items in the first ListView will adapt dynamically, you can use a Column of Widgets similar to this sample.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final items = [
'Apple',
'Banana',
'Carrot',
'Dog',
'Egg',
'Flower',
'Goat',
'Honey'
];
final subItems = ['1.00', '2.00', '3.00', '4.00'];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: firstList(),
),
);
}
firstList() {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Container(
padding: EdgeInsets.all(8.0),
child: Card(
child: Container(
color: Colors.lightBlue[50],
padding: EdgeInsets.all(16.0),
child: Row(
children: [
Expanded(
flex: 2,
child: Text('${items[index]}'),
),
Expanded(
flex: 1,
child: secondList(subItems),
),
],
),
),
),
);
},
);
}
secondList(List item) {
// Create List<Widget> for the second "List"
var subList = List<Widget>();
item.forEach((data) {
subList.add(
Card(
child: Container(
padding: EdgeInsets.all(16.0),
color: Colors.lightBlueAccent,
child: Text('$data'),
),
),
);
});
// Populate Column instead of ListView
return Column(
children: subList,
);
}
}

How can do card buttons fit together like Reddit App in Flutter?

I want to my card button fit together like Reddit App. How can do that?
Outside the main Row has a Container and Container' has padding height 15.0 . How can Row's widget fit that height 15.0 responsively.
Reddit card buttons
My app card buttons
This is my code;
#override
Widget build(BuildContext context) {
return new SafeArea(
top: false,
bottom: false,
child: new Card(
child: new Column(
children: <Widget>[
new Container(
padding: EdgeInsets.fromLTRB(5.0, 15.0, 5.0, 3.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Container(
color: Colors.blueGrey,
child: new Row(
children: <Widget>[
new Icon(Icons.arrow_drop_up),
new Text('Vote'),
new Icon(Icons.arrow_drop_down),
],
),
),
new Container(
color: Colors.blueGrey,
child: new Row(
children: <Widget>[
new Icon(Icons.mode_comment),
new Text('Comment'),
],
),
),
new Container(
color: Colors.blueGrey,
child: new Row(
children: <Widget>[
new Icon(Icons.share),
new Text('Share'),
],
),
),
],
),
)
],
),
),
);
}
Hello and welcome to Flutter :)
First of all you have used too much padding i.e. 15.0 so that is why your grey boxes are smaller than that of Reddit example.
I have taken a simpler approach and designed a sample control for you. Hope you like it.
import 'package:flutter/material.dart';
void main() {
runApp(RedditButtonsExample());
}
class RedditButtonsExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Reddit Buttons Example",
home: HomePage(),
theme: ThemeData(
primaryColor: Colors.white,
accentColor: Colors.white,
),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Reddit Buttons Example'),
),
body: Column(
children: <Widget>[
Expanded(child: Icon(Icons.insert_emoticon)),
RedditButtonsCard(), //Example widget.
],
),
);
}
}
//This is the example control that you need.
class RedditButtonsCard extends StatelessWidget {
const RedditButtonsCard({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
color: Colors.black,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FlatButton.icon(
textColor: Colors.white,
icon: Icon(
Icons.thumbs_up_down,
color: Colors.white,
),
label: Text('Vote'),
onPressed: () {},
),
FlatButton.icon(
color: Colors.white30,
textColor: Colors.white,
icon: Icon(
Icons.mode_comment,
color: Colors.white,
),
label: Text('Comment'),
onPressed: () {},
),
FlatButton.icon(
textColor: Colors.white,
icon: Icon(
Icons.share,
color: Colors.white,
),
label: Text('Share'),
onPressed: () {},
),
],
),
),
);
}
}
I used Table and TableRow and I found what I wanted. Off the topic but I want to say this; I found this solution in my dream. I said my self "you have to use DataTable or something then you got what you want." My subconscious full of with Flutter I guess. :D
#override
Widget build(BuildContext context) {
return new SafeArea(
top: false,
bottom: false,
child: new Card(
child: new Column(
children: <Widget>[
new Table(
children: [
new TableRow(
children: [
new InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 15.0, 5.0, 15.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Icon(FontAwesomeIcons.arrowAltCircleUp, color: Colors.white),
Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0),
child: new Text('Vote', style: TextStyle(color: Colors.white)),
),
new Icon(FontAwesomeIcons.arrowAltCircleDown, color: Colors.white),
],
),
),
),
new InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 15.0, 5.0, 15.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Icon(Icons.mode_comment, color: Colors.white),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text('Comment', style: TextStyle(color: Colors.white)),
),
],
),
),
),
new InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 15.0, 5.0, 15.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Icon(Icons.share, color: Colors.white),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text('Share', style: TextStyle(color: Colors.white)),
),
],
),
),
),
],
),
],
),
],
),
),
);
}

Listview that contain fixed listview

I would like to basically make a Settings Screen. Actually my screen look like that with Settings section that are composed of one title and a non-scrollable list view. I would like to put these sections in a list view to make the screen scrollable and to make every settings section following the last one.
Here is my actual screen.
And here is my code.
Widget build(BuildContext context) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: SettingSection('Communication', [
SettingsPayload('Email', 'Switch', () => (print('Function :)'))),
SettingsPayload('Notifications', 'Switch'),
])),
Expanded(
child: SettingSection('Hello', [
SettingsPayload('Email', 'Normal', () => print('value'),
Icons.arrow_forward_ios),
SettingsPayload('Notifications', 'Normal', () => print('hello')),
]))
],
));
How I build each list
buildlistSettings() {
return ListView.builder(
physics: ScrollPhysics(parent: NeverScrollableScrollPhysics()),
padding: const EdgeInsets.all(15.0),
itemBuilder: (context, i) {
if (i < widget.listSettings.length) {
return Column(
children: <Widget>[
buildTileSettings(widget.listSettings[i]),
Divider(),
],
);
}
});
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.only(left : 10.0),
height: 25.0,
decoration:
BoxDecoration(color: Color.fromRGBO(223, 230, 233, 0.5), border: Border(bottom: BorderSide(color: Color.fromRGBO(223, 230, 233, 0.5), width: 1.0))),
child: Row(children: <Widget>[Text(
widget.title,
style: TextStyle(fontSize: 15.0, color: Colors.blueGrey),
)])),
Expanded(child: buildlistSettings()),
],
),
);
}
}
I think there's a set of problems here not least of which is trying to put a ListView inside a ListView (and having to turn off scrolling), but mostly the use of Expanded which tries to fill up all the space in the relevant direction, but inside another container, which is itself unbounded.
I would use a ListView at the root, then build up the children using simple Column, ListTile and Divider widgets. Here's a working example (duplicated your data to ensure there's enough to scroll):
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: ListView(
children: <Widget>[
SettingSection('Communication', [
SettingsPayload('Email', 'Switch', () => (print('Function :)'))),
SettingsPayload('Notifications', 'Switch'),
]),
SettingSection('Hello', [
SettingsPayload('Email', 'Normal', () => print('value'),
Icons.arrow_forward_ios),
SettingsPayload('Notifications', 'Normal', () => print('hello')),
]),
SettingSection('Communication', [
SettingsPayload('Email', 'Switch', () => (print('Function :)'))),
SettingsPayload('Notifications', 'Switch'),
]),
SettingSection('Hello', [
SettingsPayload('Email', 'Normal', () => print('value'),
Icons.arrow_forward_ios),
SettingsPayload('Notifications', 'Normal', () => print('hello')),
]),
],
),
);
}
}
class SettingSection extends StatelessWidget {
final String title;
final List<SettingsPayload> payload;
SettingSection(this.title, this.payload);
#override
Widget build(BuildContext context) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10.0),
height: 25.0,
decoration: BoxDecoration(
color: Color.fromRGBO(223, 230, 233, 0.5),
border: Border(
bottom: BorderSide(
color: Color.fromRGBO(223, 230, 233, 0.5),
width: 1.0))),
child: Row(children: <Widget>[
Text(
this.title,
style: TextStyle(fontSize: 15.0, color: Colors.blueGrey),
)
])),
_buildListSettings(context),
],
),
);
}
Widget _buildListSettings(BuildContext context) {
List<Widget> items = List<Widget>();
for (var setting in this.payload) {
// TODO: Add logic here to determine what kind of setting widget to
// create based on the payload.
items.add(ListTile(
title: Text(setting.title),
trailing: Icon(setting.icon),
));
items.add(Divider());
}
return Column(children: items);
}
}
class SettingsPayload {
final String title;
final String type;
final Function handler;
final IconData icon;
SettingsPayload(this.title, this.type, [this.handler, this.icon]);
}
You could use ListView.builder at the root level if your incoming settings data is variable and create SettingSection widgets for each item. Depends how you're handling your data.

Resources