stack in listview flutter infinite height - flutter

i want to put a card between an image and the rest of the page
so i used stack in listview builder but it doesn't give the expected result
what i want
what i get => https://i.stack.imgur.com/Oxy41.jpg
ListView.builder(
itemCount: 1,
itemBuilder: (context, i) {
return Stack(
children: <Widget>[
first(_listviewurl, _listViewData[0], _listviewwe9t),
Container(
padding: EdgeInsets.all(40),
child: Text(
"News",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 32),
),
),
Positioned(
width: MediaQuery.of(context).size.width / 2.5,
height: MediaQuery.of(context).size.height / 5,
left: MediaQuery.of(context).size.width / 9,
top: MediaQuery.of(context).size.height / 1.9,
child: Card(
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: Image.asset(
"images/img1.jpg",
fit: BoxFit.fill,
),
),
),
],
);
},
),

Because your card is in your listview and your listview's height is the same with your first Widget, you can add Container as parent widget of your Stack widget and set height for it:
Container(
child: Stack(...)
)

Related

how can i give percentage height in stack with respect to other children in flutter stack widget

here is my code
Scaffold(
// backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
title: const Text("Live Shows"),
),
body: MasonryGridView.builder(
physics: const BouncingScrollPhysics(),
gridDelegate: const SliverSimpleGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
mainAxisSpacing: 7,
crossAxisSpacing: 7,
itemCount: urs.length,
itemBuilder: ((context, index) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: ColorsItems().color3,
width: 1,
)),
child: Stack(children: [
Positioned(
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: CachedNetworkImage(
imageUrl: urs[index],
imageBuilder: (context, imageProvider) =>
Image(image: imageProvider),
),
)),
//Container 2
Positioned.fromRelativeRect(
rect: RelativeRect.fromLTRB(2, 30, 4, 3),
child: Container(
color: Colors.black,
))
]),
);
}),
));
I want to to set height and width of container 2 as like 30 percent of the height of the upper widget and same width as upper widget has
is there any way to do this
thanks in a advance
You can use FractionallySizedBox .
Positioned.fill(
child: FractionallySizedBox(
heightFactor: .3,//your value
widthFactor: 1,
alignment: Alignment.bottomCenter,
child: Container(
color: Colors.black,
child:
)),
),
FractionallySizedBox(
widthFactor: 0.7,
heightFactor: 0.25,
child: Container(
color: Colors.amber,
),
)
You can set flex as 3 of the 1st Container and 2nd Container flex as 1 so you will achieve height of 2nd Container as 30 percent of height of 1st Container , here is an example code
Stack(
fit: StackFit.expand,
children: [
Column(
children: [
Expanded(
flex: 3,
child: Container(
color: Colors.black,
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.green,
),
),
],
)
],
),

GridView Flutter

i'm trying to do this page
but what i get is this
this is my code
SingleChildScrollView(
child: Column(
children: [
Center(
child: Container(
margin: EdgeInsets.all(20),
width: 230,
height: 40,
child: ElevatedButton(
onPressed: () {
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Color(0xff28CC61)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text("Add a book", style: TextStyle(
fontSize: 20
),),
),
),
),
),
Container(
child: Text("Explore between 10 books", style: TextStyle(
fontSize: 20
),),
),
Container(
//adding: EdgeInsets.all(12),
child: SingleChildScrollView(
child: GridView.builder(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1,
crossAxisSpacing: 20,
crossAxisCount: 2,
mainAxisSpacing: 8),
itemCount: books.length,
itemBuilder: (BuildContext ctx, index) {
return Container(
width: 50,
height: 100,
child: Card(
color: Color(0xFFEDEDED),
child: Column(
children: [
Image.asset(books[index].image, height: 150
,
width: 150,fit: BoxFit.cover,),
],
),
),
);
}),
),
),
],
),
),
ignore the colors and styles i want how to do the page
i stucked on gridview and how to write text below the picture + How can I fix my code to do it? So each image has same size as others? i tried to see the grid view documentation and i could not find anything.
Change childAspectRatio : 1 to childAspectRatio:0.7. childaspectRatio defines the ratio between width and height of children. If you set it as 1 you will get a square shaped widget. More than 1 is horizontal rectangle and less than 1 gives vertical rectangle.

Draggable Scrollable Sheet becomes unscrollable when we set it's child to a column

I have the following code for a DraggableScrollableSheet in Flutter.
DraggableScrollableSheet(
builder: (BuildContext context, ScrollController scrollController) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(35),
topRight: Radius.circular(35),
),
child: Container(
color: ColorData.secondaryColor,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
child: Column(
children: [
Container(
height: 3,
width: 30,
decoration: BoxDecoration(
color: ColorData.primaryDividerColor,
borderRadius: BorderRadius.circular(16),
),
),
const SizedBox(
height: 18,
),
SizedBox(
width: _screenWidth,
child: const Text(
'Exchange Houses',
textAlign: TextAlign.start,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
const SizedBox(
height: 8,
),
SizedBox(
width: _screenWidth,
child: const Text(
'(Tap to select)',
textAlign: TextAlign.start,
),
),
const SizedBox(
height: 10,
),
Expanded(
child: ListView.separated(
itemCount: 5,
itemBuilder: (context, index) => const ExchangeHouseCard(
id: 1,
houseName: 'Test House',
houseContactNumber: '+94 77123456',
houseUrl:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrLlwS2ymz1oFL10jTbD7QMcCffrrAzUAbMA&usqp=CAU',
houseImageUrl:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrLlwS2ymz1oFL10jTbD7QMcCffrrAzUAbMA&usqp=CAU',
houseLatitude: 7.0012345,
houseLongitude: 20.301456,
userCurrencyName: 'USD',
convertingCurrencyName: 'LKR',
exchangeRate: 200.00,
change: 500.00,
changeInConvertingCurrency: 1200.00,
),
separatorBuilder: (context, index) => const SizedBox(
height: 5,
),
),
),
],
),
),
),
);
},
),
In the above code, I am trying to make my DraggableScrollableSheet be able be to dragged upwards or collapsed downwards when user drags the sheet. No matter how I try, I can not drag or collapse the sheet. It stays where it is.
Furthermore, something interesting happens if I set controller property of my ListView to the scrollController I get from the builder method in DraggableScrollableSheet. In this case, the DraggableScrollableSheet becomes draggable if we try to scroll the ListView.
But I want the DraggableScrollableSheet to be draggable if I drag from a general area of the sheet. How to implement this to the above DraggableScrollableSheet?
(I also tried wrapping the widget that is being returned inside the builder method with a ListView and setting controller property of the ListView to scrollController that I get from the builder method. But this also gives a render error. I could not find a way to fix this.)
Can someone please help?
You need to give isScrollControlled to true and set the height
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) {
return DraggableScrollableSheet(
initialChildSize: 0.9,
maxChildSize: 0.9,
builder: (BuildContext context, ScrollController scrollController) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(35),
topRight: Radius.circular(35),
),
child: Container(
color: ColorData.secondaryColor,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
child: Column(
children: [
Container(
height: 3,
width: 30,
decoration: BoxDecoration(
color: ColorData.primaryDividerColor,
borderRadius: BorderRadius.circular(16),
),
),
const SizedBox(
height: 18,
),
SizedBox(
width: _screenWidth,
child: const Text(
'Exchange Houses',
textAlign: TextAlign.start,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
const SizedBox(
height: 8,
),
SizedBox(
width: _screenWidth,
child: const Text(
'(Tap to select)',
textAlign: TextAlign.start,
),
),
const SizedBox(
height: 10,
),
Expanded(
child: ListView.separated(
itemCount: 5,
controller: scrollController,
itemBuilder: (context, index) =>
const ExchangeHouseCard(
id: 1,
houseName: 'Test House',
houseContactNumber: '+94 77123456',
houseUrl:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrLlwS2ymz1oFL10jTbD7QMcCffrrAzUAbMA&usqp=CAU',
houseImageUrl:
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrLlwS2ymz1oFL10jTbD7QMcCffrrAzUAbMA&usqp=CAU',
houseLatitude: 7.0012345,
houseLongitude: 20.301456,
userCurrencyName: 'USD',
convertingCurrencyName: 'LKR',
exchangeRate: 200.00,
change: 500.00,
changeInConvertingCurrency: 1200.00,
),
separatorBuilder: (context, index) =>
const SizedBox(
height: 5,
),
),
),
],
),
),
),
);
},
);
});

Flutter: Rendering working fine on android device but overflowing on iOS device of a different size

From the AppWidget (home of the material app), I am returning a GridView. Below is the code of AppWidget's build method:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarWidget(widget.title),
body: SafeArea(
child: GridView.count(
physics: ScrollPhysics(),
padding: EdgeInsets.all(MediaQuery.of(context).size.width * 0.03),
shrinkWrap: true,
crossAxisCount: 2,
crossAxisSpacing: MediaQuery.of(context).size.width * 0.03,
mainAxisSpacing: MediaQuery.of(context).size.width * 0.03,
children: List.generate(workoutList.length, (index) {
return WorkoutOverviewWidget(workoutList[index]);
})),
),
);
}
Below is the code for WorkoutOverviewWidget's build method:
Widget build(BuildContext context) {
return InkWell(
splashColor: Colors.black,
onTap: () => gotoWorkoutDetailsWidget(context),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
child: Container(
height: (MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
kToolbarHeight) *
(0.30),
width: MediaQuery.of(context).size.width * (0.4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0),
),
child: Image.asset(
getWorkoutImagePath(this._workout.type),
height: (MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
kToolbarHeight) *
(0.225),
width: double.infinity,
fit: BoxFit.cover,
),
),
Positioned(
bottom: 10,
right: 10,
child: Container(
decoration: BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
padding: EdgeInsets.all(5),
child: Text(
Utils.getEnumName(this._workout.type.toString()),
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.w700),
),
),
)
],
),
SizedBox(
height: (MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
kToolbarHeight) *
(0.015),
),
Row(
children: [
SizedBox(
width: 4,
),
Icon(
Icons.calendar_today_rounded,
size: 20,
),
SizedBox(
width: 3,
),
Utils.displayText(
text: getReadableTimestamp(this._workout.timestamp),
allPadding: 5,
fontSize: 15,
fontWeight: FontWeight.w700,
fontFamily:
Theme.of(context).textTheme.headline1.fontFamily,
),
],
),
],
),
),
),
);}
I have used MediaQuery to avoid hardcoding the size of any widget. The code is working fine when I tested it on the Google Pixel emulator but overflows on iPhone 12 Max Pro emulator. Below are the screenshots:
Output on Google Pixel emulator:
Output on iPhone 12 Max Pro emulator:
What is the thing I am doing wrong?
Using MediaQuery is a good first step, but this will adjust your dimensions according to the screen, but if those dimensions are bigger than their parent, they will over Flow.
Wrap your sized box with an Expanded, wrap your Last Row with an expanded also, and it's children, which are overflowing [children of row] in an expanded], the overflow will go away, then you can readjust the heights as you want. It has nothing to do with android or iOS, it's only related to the dimensions of the screens you are using. It can overflow on an android device with similar device dimensions as the one you are using for iOS. Try it out, it would solve your problem.
Solved it by not defining the height of the image in ClipRRect explicitly but instead wrapping them in the Expanded() widget with flex property defined to adjust the percentage of height distributed between the children in column. Updated code for WorkoutOverviewWidget's build method:
return InkWell(
splashColor: Colors.black,
onTap: () => gotoWorkoutDetailsWidget(context),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
child: Container(
height: this._availableHeight * (0.30),
width: this._screenWidth * (0.4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 4,
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0),
),
child: Image.asset(
getWorkoutImagePath(this._workout.type),
width: double.infinity,
fit: BoxFit.cover,
),
),
Positioned(
bottom: 10,
right: 10,
child: Container(
decoration: BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
padding: EdgeInsets.all(5),
child: Text(
Utils.getEnumName(this._workout.type.toString()),
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontWeight: FontWeight.w700),
),
),
)
],
),
),
Expanded(
flex: 1,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: this._screenWidth * (0.02),
),
Icon(
Icons.calendar_today_rounded,
size: 20,
),
SizedBox(
width: this._screenWidth * (0.01),
),
Utils.displayText(
text: getReadableTimestamp(this._workout.timestamp),
allPadding: 5,
fontSize: 15,
fontWeight: FontWeight.w700,
fontFamily:
Theme.of(context).textTheme.headline1.fontFamily,
),
],
),
),
],
),
),
),
);

How to display text below the image?

i'm trying to display text of each picture below to that picture in an alertdialog like rating a score. I tried to use stack widget and this is the result the result. Text is in front of the picture and not display below th picture but i just want it to display below the picture. How can I do it correctly?
#override
Widget build(BuildContext context) {
return Container(
height: 60,
width: MediaQuery.of(context).size.width*0.75,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: pic.length,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.only(right: 10),
child: InkWell(
onTap: () {
},
child: Stack(
children: <Widget> [
Image.asset('assets/images/'+pic[index].toString()+'.png', height: 70, width: 70,),
Text(pic[index].toString())
])));
}));
}
}
reverse the order of your widgets like so:
First the InkWell Widget with a container child and to that container pass a column widget with the icon and then the text. I've used GestureDetector in this example..
GestureDetector(
onTap: #Do Something
child: Container(
child: Column(
children: <Widget>[
Icon('Your Icon Here'),
Text('Your Text Here')
],
),
),
),
this code if u not want use STACk
Container(
constraints: new BoxConstraints.expand(
height: 200.0,
),
alignment: Alignment.bottomLeft,
padding: new EdgeInsets.only(left: 16.0, bottom: 8.0),
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/image.jpg'),
fit: BoxFit.cover,
),
),
child: new Text('Title',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
)
),
);
and this if u want use STACK
Container(
constraints: new BoxConstraints.expand(
height: 200.0,
),
padding: new EdgeInsets.only(left: 16.0, bottom: 8.0, right: 16.0),
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage('assets/image.jpg'),
fit: BoxFit.cover,
),
),
child: new Stack(
children: <Widget>[
new Positioned(
left: 0.0,
bottom: 0.0,
child: new Text('Title',
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
)
),
),
new Positioned(
right: 0.0,
bottom: 0.0,
child: new Icon(Icons.star),
),
],
)
);
this link if u want see more https://cogitas.net/overlay-text-icon-image-flutter/
You can position elements inside your stack - positioned