infinity height in the listview of the flutter - flutter

Hi friends i am new to the flutter development here i am using the list view please find this image
Where i am want to remove the white space above and below the image make it stretch on this white spaces i am tried to sized box but its given error that double.infinity cant be used please find the below code please help me out friends
new SliverList(
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new GestureDetector(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new News_Details(
postid: latest_news_list[index]['id'],
)));
},
child: new Card(
elevation: 4.0,
margin: EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0),
child: new Row(
children: <Widget>[
**new Container(
child: new Image.network(
latest_news_list[index]['image'],
width: 150.0,
fit: BoxFit.cover,
),
),**
new Flexible(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
child: new Text(latest_news_list[index]['title']),
margin: EdgeInsets.only(left: 10.0, top: 10.0),
),
new Container(
child: new Divider(
color: secondarycolor,
),
margin: EdgeInsets.only(right: 10.0, left: 10.0),
),
new Container(
child: new Text(
latest_news_list[index]['content'],
softWrap: true,
maxLines: 4,
),
margin: EdgeInsets.only(
left: 10.0, top: 5.0, bottom: 5.0),
),
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Container(
child: new Text('VSB News'),
margin:
EdgeInsets.only(left: 10.0, top: 10.0,bottom: 10.0),
),
new Container(
child: new Text(
latest_news_list[index]['post_dt']),
margin:
EdgeInsets.only(left: 10.0, top: 10.0,right: 10.0,bottom: 10.0),
),
],
)
],
),
)
],
),
),
);
},
childCount: latest_news_list == null ? 0 : latest_news_list.length,
),
),

You can edit the line
fit: BoxFit.cover
to
fit: BoxFit.fitHeight
inside you container that grabs image from network.

I think you are trying to put a list inside another list, so the error shows
you can put the list (nested list which is inside the list) in a container and specify a height :
ListView _buildMainView(){
return new ListView(
children: <Widget>[
new Text("Main List"),
new Container(
height: 100.0,
child: new ListView(
children: <Widget>[
new Text("Nested List")
],
),
)
],
);
)

If you have a ListView with vertical scroll direction, and want it to have a infinity height, maybe you don't need a ListView.
You can use a regular Column.

Related

Flutter check if value exists in json show/hide container

I'm new to flutter, I wanna show container if a specific value exists in Kinds model, the model contains stores, groceries and markets I don't know how to do it exactly please help me with my code
the controller returns the json is kindController.kindDataList
so if market exist in the json then show
child: HomeFlatBtn(image: 'market', height: 150, currentTab: 1,),
Container(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Dimensions.PADDING_SIZE_SMALL),
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Column(children: [
Padding(
padding: EdgeInsets.symmetric(vertical: Dimensions
.PADDING_SIZE_SMALL,
horizontal: Dimensions.PADDING_SIZE_SMALL),
child: HomeFlatBtn(
image: 'market', height: 150, currentTab: 1,),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: Dimensions
.PADDING_SIZE_SMALL),
child: HomeFlatBtn(
image: 'grocery', height: 150, currentTab: 1,),
),
]
),
),
Expanded(child: HomeFlatBtn(image: 'food',
height: 0,
currentTab: 1),
),
],
),
),
),
),
You can use Visibility widget for this.
Just wrap Container with Visibility. Like this:
Visibility(
visible: true, //set this to either true or false
child: Container(
//the contents of Container
),
),
//visible decides whether your Container will be visible or not.

Refresh ListView.builder On Button Click in Flutter

I am using the below code, where I have a ListView that had a switch.
I want to implement something like when I click on the RaisedButton - it will reload the ListView and all the values of switch.value should be changed to either true or false.
The user can either change the value of the switch from items in the ListView or from the button click.
I do not have an idea on how I should change the value or all the switches in the ListView.
return Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width / 2,
height: 100,
padding: EdgeInsets.all(20),
child: RaisedButton(
onPressed: () {
},
child: Text(
BTN_START_TRIP,
style: new TextStyle(
fontSize: 20.0,
),
),
textColor: buttonFontColor,
color: buttonColor,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(15.0))
),
),
Expanded(
child: ListView.builder(
padding: EdgeInsets.all(3.0),
// Let the ListView know how many items it needs to build.
itemCount: snapshot.data.results.length,
// Provide a builder function. This is where the magic happens.
// Convert each item into a widget based on the type of item it is.
itemBuilder: (context, index){
return Container(
height: 120,
child: Card(
elevation: 10,
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onTap: () {
print(snapshot.data.results[index].original_title);
},
child: Container(
height: 120,
child: Row(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(20, 0, 5, 0),
width: MediaQuery.of(context).size.width -90,
child: Align(
alignment: Alignment.topLeft,
child: Text(snapshot.data.results[index].original_title,
textAlign: TextAlign.left,
style: TextStyle(fontSize: defaultTitleFontsize, color: defaultFontColor),
maxLines: 5),
),
),
Container(
padding: EdgeInsets.fromLTRB(20, 0, 5, 0),
child: Align(
alignment: Alignment.topLeft,
child: Text(snapshot.data.results[index].original_language,textAlign: TextAlign.left,style: TextStyle(fontSize: defaultsubTitleFontsize, color: defaultFontColor)),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
child: Switch(
value: false,
onChanged: (value){
setState(() {
print(value);
});
}
),
),
],
),
]
),
),
),
),
);
},
),
)
],
);
You'll need to have a variable to decide if the switch should be on or off. And during a certain event (click of button e.g) set the variable to appropriate value & re-trigger the build (re-painting of the UI) by calling setState. You'll need to have the above logic part of a stateful widget to accomplish that.

Dynamic height of listview builder item

I am unable to set the dynamic size to my list item of list view builder, every time it shows blank screen and when I specify a constant size it works.
I tried by using column by setting mainAxisSize=minimum and by using container as we know container wraps the child height but nothing works
listItem (GuideLines news) =>Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[Container(
decoration: BoxDecoration(image: new DecorationImage(image: AdvancedNetworkImage(
"${news.featured_image}",
useDiskCache: true,
cacheRule: CacheRule(maxAge: const Duration(days: 7)),
),fit: BoxFit.cover)),
margin: EdgeInsets.only(bottom: 10.0),
child: ListTile(
onTap: (){
print(news.web_link);
Navigator.push(context, MaterialPageRoute(builder: (context) => NewsDetailsPage(news)));
},
title: new Container(
margin: EdgeInsets.only(left: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: new Text("${DateFormat("E, d MMM y").format(CommonService.dateFormat(news.publish_date.toString()))}", style: TextStyle(fontFamily: 'SF-Display-Regular' ,fontSize: 13.0 ,color: Colors.white),),
),
SizedBox(height: 13.0),
new Flexible(
child: new Container( width: MediaQuery.of(context).size.width *0.45,
child: Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: new Text("${news.title}" ,maxLines: 3, overflow: TextOverflow.ellipsis, style: TextStyle(fontFamily: 'SF-Display-Semibold' ,fontSize: 22.0 ,color: Colors.white),),
)
),
)
],
)),
trailing: Padding(
padding: const EdgeInsets.only(right: 20),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[Icon(Icons.arrow_forward_ios, color: Colors.white),SizedBox(width: 8,)],
),
),
),
)],
);
Just add these two properties of shrinkWrap and physics to make the height of list dynamic
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), //Optional
itemCount: size,
itemBuilder: (context, position) {}
),
The problem with your code is, that you used a Flexible widget in a Column. A Flexible widget expands to the remaining space of the Column or Row. However, this only works if you have restricted the size of the Column or Row widget. Because otherwise, the size of the element in the Column would expand to infinity as the remaining space is not restricted and therefore also infinity.
When using Flexible or Expanded widgets you always need to restrict their parent size, else you get this error:
RenderFlex children have non-zero flex but incoming height constraints
are unbounded. When a column is in a parent that does not provide a
finite height constraint, for example if it is in a vertical
scrollable, it will try to shrink-wrap its children along the vertical
axis. Setting a flex on a child (e.g. using Expanded) indicates that
the child is to expand to fill the remaining space in the vertical
direction.
The solution and some cleanup of your code:
Widget listItem(GuideLines news) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AdvancedNetworkImage(
"${news.featured_image}",
useDiskCache: true,
cacheRule: CacheRule(maxAge: const Duration(days: 7)),
),
fit: BoxFit.cover),
),
margin: EdgeInsets.only(bottom: 10.0),
child: ListTile(
onTap: () {
print(news.web_link);
Navigator.push(context, MaterialPageRoute(builder: (context) => NewsDetailsPage(news)));
},
title: Container(
margin: EdgeInsets.only(left: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0, bottom: 13.0),
child: Text(
"${DateFormat("E, d MMM y").format(CommonService.dateFormat(news.publish_date.toString()))}",
style: TextStyle(fontFamily: 'SF-Display-Regular', fontSize: 13.0, color: Colors.white),
),
),
Container(
width: MediaQuery.of(context).size.width * 0.45,
padding: const EdgeInsets.only(bottom: 20.0),
child: new Text(
"${news.title}",
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontFamily: 'SF-Display-Semibold', fontSize: 22.0, color: Colors.white),
),
)
],
),
),
trailing: Padding(
padding: const EdgeInsets.only(right: 28),
child: Icon(Icons.arrow_forward_ios, color: Colors.white),
),
),
);
}
In your specific case, this Flexible widget was redundant anyway.

flutter create ui using stack . Floating Button should be over the widget

I am tring to create ui as below image. but button hide behind the list. Also faces issue button not click when used Positioned widget for button.Please suggest how to create below UI using Stack widget with ListView & Floating button.
UI
Container(
color: Colors.grey,
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(
height: 250.0,
width: MediaQuery.of(context).size.width,
child: Image.asset(
"images/1.jpg",
fit: BoxFit.cover,
),
)
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
height: 220.0,
),
Container(
padding: EdgeInsets.only(right: 15.0),
child: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.favorite),
),
),
],
),
Column(
children: <Widget>[
Container(
height: 250.0,
),
Container(
height: MediaQuery.of(context).size.height - 250.0,
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text("Title $index"),
leading: Icon(Icons.home),
),
);
},
itemCount: 15,
),
),
],
)
],
),
],
),
);
As per documentation (https://docs.flutter.io/flutter/widgets/Stack-class.html):
The stack paints its children in order with the first child being at the bottom
So your Stack children's order is wrong. Your current order is:
Header
Button
List
But it should be:
Header
List
Button
Otherwise list is overlapping button.

How to make responsive images in flutter?

I am using Gridview.builder to make a grid of cards. I didn't find any attribute inside Gridview.builder to decide the size of a single card also inside the Card widget I didn't find any attribute to decide the size of the card.
Further to that, I want to make the image and a text inside the card responsive, here is the code of the method which returns me the card -
Card myCard(String houseName, String houseImageUrl) {
return new Card(
elevation: 5.0,
child: new InkWell(
child: new Container(
alignment: Alignment.center,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Image.network(
houseImageUrl,
height: 180.0,
width: 180.0,
),
new Padding(
padding: const EdgeInsets.all(8.0),
child: new Center(
child: new Text(
houseName,
style: new TextStyle(fontSize: 16.0),
textAlign: TextAlign.center,
),
),
),
],
),
),
));
I have used Gridview.builder as follows ("data" is the data coming from API)
new GridView.builder(
itemCount: data == null ? 0 : data.length,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
var housename = data.keys.toList()[index].toString();
return myCard(
housename, data[housename]['image'].toString());
})));
The output of this code shows cards like this
Screenshot of above code output
You can use the fit property.
new Image.network(
houseImageUrl,
fit: BoxFit.contain,
height: 180.0,
width: 180.0,
),
The propertyfit: BoxFit.containwill limit the whole image to defined height.
For the Card Size you can use the childAspectRatio attribute inside gridDelegate as follows ->
new GridView.builder(
itemCount: data == null ? 0 : data.length,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: (1 / 1),
crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
var housename = data.keys.toList()[index]
.toString();
return myCard(
housename, data[housename]['image'].toString());
}
)
In above code 1/1 indicates that your cards will have the square shape
further, for image responsiveness, you can use a fit property as #ap14, The code will be like ->
Card myCard(String charName, String charImageUrl) {
return new Card(
elevation: 5.0,
child: new InkWell(
child: new Container(
alignment: Alignment.center,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Padding(
padding:const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
child: new Image.network(
charImageUrl,
fit: BoxFit.contain,
height: 150.0,
width: 150.0,
),
),
new Padding(
padding: const EdgeInsets.all(8.0),
child: new Center(
child: new Text(
charName,
style: new TextStyle(fontSize: 16.0),
textAlign: TextAlign.center,
),
),
),
],
),
),
)
);
}
use ResponsiveGridList from the responsive_grid package
you only specify your desired width and it chooses how many image to fit in a row, you can also set squareCells to true so that images will be forced to layout equal width and height