text fitting the expandedlist header's width - dart

am using my customized ExpandedList .. but the header is overflowed when the text is long ....
and this is how am using it:
new CustomExpansionPanelList2(
expansionCallback: (int index, bool isExpanded) {
setState(() {
faqList[index].isExpanded =
!faqList[index].isExpanded;
});
},
children: faqList.map((Faq i) {
return new ExpansionPanel(
headerBuilder:
(BuildContext context, bool isExpanded) {
return new Container(
child: new Row(
children: <Widget>[
SizedBox(child: Text(
i.question,
style:
TextStyle(color: Color(0xff606060)),
),),
],
),
);
},
isExpanded: i.isExpanded,
body: new Center(
child: new Padding(
padding: EdgeInsets.all(10.0),
child: Text(i.answer),
),
),
);
}).toList(),
),
I want the text to be in two lines or more is needed to make it fit the width of the Expanded list..
How to achieve this?

Just replace SizedBox by Expanded in the headerBuilder
return new Container(
child: new Row(
children: <Widget>[
Expanded(child: Text(
i.question,
style:
TextStyle(color: Color(0xff606060)),
),),
],
),
);

Related

How to wrap row items in a card with flutter

I have a card that contains row of items (text and checkbox widgets). The problem is that the card can only fill up limited space each row, but it isn't going to the next line in the row. I tried using the wrap widget but it had no effect. I keep getting this:
As you can see it is not wrapping to the next but trying to fit everything in that one line. Here is my code:
Widget _buildCategories() {
return Card(
margin: const EdgeInsets.only(top: 20.0),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text(
'Categories',
style: TextStyle(fontFamily: 'MonteSerrat', fontSize: 16.0),
),
Wrap(
children: <Widget>[
Row(
children: <Widget>[
_checkBox('Gaming'),
_checkBox('Sports'),
_checkBox('Casual'),
_checkBox('21 +'),
_checkBox('Adult'),
_checkBox('Food'),
_checkBox('Club'),
_checkBox('Activities'),
_checkBox('Shopping'),
],
)
],
)
],
),
));
}
Widget _checkBox(String category) {
return Expanded(
child: Column(
children: <Widget>[
Text(
'$category',
textAlign: TextAlign.center,
style: TextStyle(fontFamily: 'MonteSerrat'),
),
Checkbox(
value: false,
onChanged: (value) {
// We will update the value to the firebase data here
print('updated value to: $value');
},
)
],
));
}
I fixed your code with the following changes:
Removed Row widget inside Wrap.
Removed Expanded widget.
Add the property maxLines to your Text widget.
Widget _buildCategories() {
return Card(
margin: const EdgeInsets.only(top: 20.0),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text(
'Categories',
style: TextStyle(fontFamily: 'MonteSerrat', fontSize: 16.0),
),
Wrap(
children: <Widget>[
_checkBox('Gaming'),
_checkBox('Sports'),
_checkBox('Casual'),
_checkBox('21 +'),
_checkBox('Adult'),
_checkBox('Food'),
_checkBox('Club'),
_checkBox('Activities'),
_checkBox('Shopping')
],
)
],
),
));
}
Widget _checkBox(String category) {
return Column(
children: <Widget>[
Text(
'$category',
maxLines: 1,
textAlign: TextAlign.center,
style: TextStyle(fontFamily: 'MonteSerrat'),
),
Checkbox(
value: false,
onChanged: (value) {
// We will update the value to the firebase data here
print('updated value to: $value');
},
)
],
);
}
}
Also you can add the properties runSpacing and spacing to your Wrap widget to give more space between your items in horizontal and vertical.
Wrap(
runSpacing: 5.0,
spacing: 5.0,
More info here: https://api.flutter.dev/flutter/widgets/Wrap-class.html

How to buid Card?

I'm new on Flutter and I'm now working on my first project, then in one of my page I'm building form in order to collect informations, so I created two Card but went I'm trying adding some TextField in the second one, all the the content disappear.
Please Help :(
import 'package:flutter/material.dart';
import 'customInputField.dart';
class DropDown extends StatefulWidget {
#override
_DropDownState createState() => _DropDownState();
}
class _DropDownState extends State<DropDown> {
// Here we're going to define the LIST
List _cities = ["Douala","Yaoundé"];
List _weight = ["0-1","1-3","3-5"];
List _dimensions = ["A5","A4","A3","A2"];
// End
var resultsList = new List.filled(3, "");
#override
void initState(){
// Here we're going to set the initial values
resultsList[0] = "Douala";
resultsList[1] = "0-1";
resultsList[2] = "A5";
return super.initState();
}
// Here we're going to create the method which will build and update the dropDown menu
_fieldDropDown(List theList, int resultPosition, var dbField) {
return new FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(),
child: new DropdownButtonHideUnderline(
child: new DropdownButton(
value: this.resultsList[resultPosition],
isDense: true,
onChanged: (dynamic newValue) {
setState(() {
this.resultsList[resultPosition] = newValue;
state.didChange(newValue);
print(
'The List result = ' + this.resultsList[resultPosition]);
//write newValue to a database field, which can be used in the override init to set the field originally
});
},
// Comment to remove Error
items: theList.map((dynamic value) {
return new DropdownMenuItem(
value: value,
child: new Text(value),
);
}).toList(),
),
),
);
},
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: Container(
decoration: new BoxDecoration(
color: Color.fromRGBO(0x12, 0x34, 0x55, 0.9),
),
child: new Form(
//key: _formKey,
autovalidate: true,
child: new ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: [
Card(
child: Padding(
padding: EdgeInsets.fromLTRB(8, 20, 8, 10),
child: Column(
children: <Widget>[
Text('Informations sur le colis',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, ),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text('Pli'),
new Radio(
value: 0,
groupValue: null,
onChanged: null
),
new Text('Colis'),
new Radio(
value: 1,
groupValue: null,
onChanged: null
)
]
),
//create some fields, hand in the list
Row(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width*.3,
child: Text('Départ:', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
),
Container(
width: MediaQuery.of(context).size.width*.5,
child: _fieldDropDown(_cities, 0, 'colorDBfield')
)
],
),
Row(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width*.3,
child: Text('Poids:', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
),
Container(
width: MediaQuery.of(context).size.width*.5,
child: _fieldDropDown(_weight, 1, 'dogDBfield'),
)
],
),
Row(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width*.3,
child: Text('Dimensions:', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
),
Container(
width: MediaQuery.of(context).size.width*.5,
child: _fieldDropDown(_dimensions, 2, 'peopleDBfield'),
)
],
),
],
)),
),
Card(
child: Padding(
padding: EdgeInsets.fromLTRB(8, 20, 8, 10),
child: Column(
children: <Widget>[
Text('Informations sur le destinataire',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, ),
),
Row(
children: <Widget>[
new TextField(
decoration: InputDecoration(
border: OutlineInputBorder()
),
),
],
)
],
),
),
)
],
)
),
),
);
}
}

Get card data object in card Buttontheme bar

Good morning,
I'm new on Flutter.
I need to open a new page from a card after a button press. To open the new page I need the card data object that I use to show the information (data[X]). The button for open the new page is located in ButtonTheme.bar but in this location I don't have my "data[X]" object.
This is my code:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Records Page", style: TextStyle(color: Colors.white)),
iconTheme: new IconThemeData(color: Colors.white),
backgroundColor: Color.fromRGBO(32, 38, 48, 1),
),
drawer: MainDrawer(),
body: new ListView.builder(
//reverse: true,
itemCount: reversedData != null ? reversedData.length : 0,
itemBuilder: (BuildContext ctxt, int index) {
if (reversedData[index].stop != null) {
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
leading: Icon(Icons.calendar_today),
title: Text('Last Period'),
//subtitle: Text('Music by Julie Gable. Lyrics by Sidney Stein.'),
),
new Container(
margin: EdgeInsets.symmetric(horizontal: 15),
child: new ListView(
shrinkWrap: true,
children: <Widget>[
new Text(
"Hour: ${reversedData[index].hourType.description}"),
new Text("Job: ${reversedData[index].job.description}"),
new Text(
"Opened at: ${DateFormat.yMd().add_jm().format(DateTime.parse(reversedData[index].start))}"),
new Text(
"Closed at: ${DateFormat.yMd().add_jm().format(DateTime.parse(reversedData[index].stop))}"),
],
),
),
ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: ButtonBar(
children: <Widget>[
FlatButton(
child: const Text('Modify',
style: TextStyle(
color: Color.fromRGBO(32, 38, 48, 1))),
onPressed: () {
Navigator.push(context, new MaterialPageRoute(builder: (__) => new PeriodEditPage(toChangeData: //my card data? ,)));
},
),
],
),
),
],
),
);
}
}));
}
I simply need to have the specific card data when I'm going to open the new page.
Hope I was clear.
Thank you
The trick is to declare your data in your statefulWidget (or statelessWidget) then use then wherever you want.
You can also create an object data where you'll have all your information instanciate one into your widget then pass it to another screen.
Here's an intro about passing data : https://flutter.dev/docs/cookbook/navigation/passing-data
Finally I found the solution to my problem:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Records Page", style: TextStyle(color: Colors.white)),
iconTheme: new IconThemeData(color: Colors.white),
backgroundColor: Color.fromRGBO(32, 38, 48, 1),
),
drawer: MainDrawer(),
body: new ListView.builder(
//reverse: true,
itemCount: reversedData != null ? reversedData.length : 0,
itemBuilder: (BuildContext ctxt, int index) {
if (reversedData[index].stop != null) {
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const ListTile(
leading: Icon(Icons.calendar_today),
title: Text('Last Period'),
//subtitle: Text('Music by Julie Gable. Lyrics by Sidney Stein.'),
),
new Container(
margin: EdgeInsets.symmetric(horizontal: 15),
child: new ListView(
shrinkWrap: true,
children: <Widget>[
new Text(
"Hour: ${reversedData[index].hourType.description}"),
new Text(
"Job: ${reversedData[index].job.description}"),
new Text(
"Opened at: ${DateFormat.yMd().add_jm().format(DateTime.parse(reversedData[index].start))}"),
new Text(
"Closed at: ${DateFormat.yMd().add_jm().format(DateTime.parse(reversedData[index].stop))}"),
],
),
),
ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: ButtonBar(
children: <Widget>[
FlatButton(
child: const Text('Modify',
style: TextStyle(
color: Color.fromRGBO(32, 38, 48, 1))),
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (__) => new PeriodEditPage(
toChangeData: reversedData[index],
)));
},
),
],
),
),
],
),
);
}
}));
}
My problem was solved thank to this line:
toChangeData: reversedData[index],
This code permit to open every card details with the same object used to populate my card.
I haven't understand properly what happen with the object reference but it works for me.

How to customize dropdown button

am trying to create a dropdown button which has an icon .. i want the whole dropdown to be underlined and also i want to set icon from my assets not from the icons.. plus i want to manage its height..
how to achive all of this?
what am doing right now is:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new InputDecorator(
decoration: const InputDecoration(
icon: const Icon(
Icons.flag,
color: Color(0xFF49C275),
),
),
child: DropdownButtonHideUnderline(
child: new DropdownButton<Gender>(
hint: new Text("المدينة"),
value: selectedGender,
onChanged: (Gender newValue) {
setState(() {
selectedGender = newValue;
});
},
items: genders.map((Gender gender) {
return new DropdownMenuItem<Gender>(
value: gender,
child: new Text(
gender.gender,
style:
new TextStyle(color: Color(0xFF707070)),
),
);
}).toList(),
),
),
),
],
),
and am getting this result:
when i want it to look like this:
How to do this?
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new InputDecorator(
decoration: const InputDecoration(
// use prefixIcon instead of icon
prefixIcon: const Icon(
Icons.flag,
color: Color(0xFF49C275),
),
),
child: DropdownButtonHideUnderline(
child: new DropdownButton<Gender>(
hint: new Text("المدينة"),
value: selectedGender,
onChanged: (Gender newValue) {
setState(() {
selectedGender = newValue;
});
},
items: genders.map((Gender gender) {
return new DropdownMenuItem<Gender>(
value: gender,
child: new Text(
gender.gender,
style:
new TextStyle(color: Color(0xFF707070)),
),
);
}).toList(),
),
),
),
],
),

Flutter: Future Builder fetch multiple data

I am consulting the news section of my website.
I'm using Future Builder to get the data from the web.
The problem I get is related to the image that I try to show on the screen.
And when there is a lot of news, the data load takes a long time and I do not know if there is a solution for loading faster.
I am consulting the text of the news through a json.
At that moment you get the URL of another JSON where the image is in thumbnail format.
I hope to solve this problem, I appreciate any help.
News.dart - Code
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: searchBar.build(context),
key: _scaffoldKey,
body: new Container(
color: Colors.grey[800],
child: new RefreshIndicator(
child: new ListView(
children: <Widget>[
new FutureBuilder<List<Post>>(
future: fetchPosts(URLWEB),
builder: (context, snapshot) {
if(snapshot.hasData) {
List<Post> posts = snapshot.data;
return new Column(
children: posts.map((post2) => new Column(
children: <Widget>[
new Card(
margin: new EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
color: Colors.white,
child: new GestureDetector(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new FutureBuilder(
future: fetchPostsIMG(post2.imagen),
builder: (context, AsyncSnapshot<PostImg> snapshot2){
return new Container(
height: 200.0,
decoration: new BoxDecoration(
image: new DecorationImage(
image: CachedNetworkImageProvider(snapshot2.data.imagen == null ? new AssetImage('images/logotipo.png') : snapshot2.data.imagen),
fit: BoxFit.fitWidth
)
),
width: MediaQuery.of(context).size.width,
);
},
),
new ListTile(
title: new Text(post2.titulo.replaceAll("‘", "").replaceAll(
"’", "").replaceAll("–", "")
.replaceAll("…", "").replaceAll(
"”", "")
.replaceAll("“", ""),
style: new TextStyle(
color: Colors.black,
fontSize: 18.0,
fontWeight: FontWeight.bold),),
subtitle: new HtmlView(data: post2.informacion),
dense: true,
)
],
),
onTap: () {
//Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context)=> new WebView(url: post2.urlweb, titulo: titulo)));
},
)
)
],
)).toList(),
);
}
else if(snapshot.hasError)
{
return new Container();
}
return new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.all(50.0)),
new CircularProgressIndicator(),
],
),
);
},
),
],
),
onRefresh: _autoRefresh
),
),
);
}
}
It's because you are trying to access imagen on null object. You can do hasData check like below
CachedNetworkImageProvider(snapshot2.hasData ? snapshot2.data.imagen : new AssetImage('images/logotipo.png')),

Resources