Flutter: Cropped Shadows on ListView - flutter

I just wanted to create a horizontal ListView in Flutter with some BoxShadows to recreate a 'neomorphism' effect.
I then realized that the shadows on the ListView Items are cropped at the edges. I already tried to adjust all kind of different paddings and margins but the problem persisted.
The weird thing is: Cards that were the Image Assets couldn't be loaded render the Shadow perfectly fine.
class _DrinkListState extends State<DrinkList> {
#override
Widget build(BuildContext context) {
return Container(
child: ListView.builder(
padding: EdgeInsets.all(30),
physics: AlwaysScrollableScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: this.widget.availableDrinks.length,
itemBuilder: (BuildContext context, int index) => Container(
child: Center(
child: LimitedBox(
child: Column(
children: <Widget>[
Expanded(
flex: 4,
child: Container(
child: Center(
child: Container(
child: Image.asset("assets/" +
this
.widget
.availableDrinks[index]
.imageName),
),
),
),
),
Expanded(
flex: 1,
child:
Text(this.widget.availableDrinks[index].label))
],
),
)),
margin: EdgeInsets.symmetric(horizontal: 20),
decoration: neodec,
padding: EdgeInsets.all(20),
width: 200,
)),
height: 300);
}
}
My BoxDecoration:
BoxDecoration neodec = BoxDecoration(
color: Color.fromRGBO(246, 246, 246, 1),
boxShadow: [
BoxShadow(color: Colors.black12, offset: Offset(10, 10), blurRadius: 10),
BoxShadow(color: Colors.white, offset: Offset(-10, -10), blurRadius: 10)
],
borderRadius: BorderRadius.all(Radius.circular(20)));

I finally managed to work around the issue by using a Card instead of Center widget in my WidgetBuilder/Container.

Related

GridView.count() doesn't scroll - Flutter

I want the Card widgets to scroll horizontally, but it's not working. I've tried and changed GridView to ListView.
Adding physics is not helping either.
Here's the code:
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Expanded(
child: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(
vertical: SizeConfig.blockSizeVertical * 2),
child: (Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Names',
style: Theme.of(context).textTheme.headline6,
),
InkWell(
onTap: () {},
child: Row(children: [
Text('show more',
style: Theme.of(context).textTheme.caption),
const Padding(
padding: EdgeInsets.only(top: 2),
child: Icon(
Icons.keyboard_arrow_left_sharp,
size: 20,
),
),
]),
),
],
)),
),
FutureBuilder<DataModel>(
future: InfoAPI('assets/itemsData.json').getDataLocally(context),
builder: (context, snapshot) {
final data = snapshot.data;
final List<String> list = getnames(data);
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).primaryColor,
),
height: SizeConfig.blockSizeVertical * 20,
// width: double.infinity,
child: GridView.count(
crossAxisCount: 1,
padding: const EdgeInsets.symmetric(
vertical: 8.0, horizontal: 10.0),
scrollDirection: Axis.horizontal,
childAspectRatio: 1,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: List.generate(list.length, (index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)),
//clipBehavior: Clip.antiAlias,
color: Theme.of(context).cardColor,
child: Center(
child: Text(
list[index],
style: Theme.of(context).textTheme.bodyText1,
)));
},
)),
);
})
],
),
);
}```
So, after long research I discovered that the 'horizontal scrolling' is working just fine on mobile, the problem was because I used chrome.
You can refer to [Horizontal listview not scrolling on web but scrolling on mobile] for more information.
Try wrapping your ListView/GridView with a Flexible Widget. Also Youve set physics to NeverScrollableScrollPhysics() so change it to some other scroll physics(like AlwaysScrollableScrollPhysics()) if you want it to be scrollable

how to make widget scale up when it selected in Flutter

I have an app that has pageView.builder and it contains 5 stack widget
how can I scale up the widget that user-selected, for example:
if the user scrolls to widget 3, widgets 1 & 2 become smaller than widget 3, and the same if he scrolls to widget 5 or 2
( the middle will become bigger than the widget on both sides)
my code :
Widget build(BuildContext context) {
// ignore: sized_box_for_whitespace
return Container(
height: 320,
child: PageView.builder(
controller: pageController,
itemCount: 5,
itemBuilder: (context, position) {
return _bulidPageItem(position);
}),
);
}
Widget _bulidPageItem(int index) {
//------------------------------------------------------------------------------
// Slide image 🚩
return Stack(
alignment: Alignment.topCenter,
children: [
Container(
margin: const EdgeInsets.only(left: 5, right: 5),
height: 220,
width: 350,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: index.isEven
? const Color(0xFFffd28d)
: const Color(0xFF89dad0),
image: const DecorationImage(
image: AssetImage('images/chineseFood.jpg'), fit: BoxFit.cover),
),
),
//------------------------------------------------------------------------------
// Slide Information 🚩
Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: const EdgeInsets.only(left: 30, right: 30, bottom: 15),
height: 130,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.3),
blurRadius: 6,
spreadRadius: 0.7,
offset: const Offset(1, 4))
],
borderRadius: BorderRadius.circular(25),
color: Colors.white,
),
//------------------------------------------------
// Slider title
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const BigText(
text: 'Chinese side',
),
//----------------------------------------------
// Slider Rating
const SizedBox(height: 10),
Row(
children: [
Wrap(
children: List.generate(
5,
(index) => const Icon(Icons.star,
color: AppColor.mainColor, size: 12),
),
),
const SizedBox(width: 10),
SmallText(text: 4.5.toString()),
const SizedBox(width: 10),
const SmallText(text: '1287 comments'),
],
),
const SizedBox(height: 20),
//----------------------------------------------
// Slider Icons
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: const [
SliderIcons(
color: AppColor.iconColor1,
text: 'Normal',
icon: Icons.circle),
SliderIcons(
color: AppColor.mainColor,
text: '1.7km',
icon: Icons.location_pin),
SliderIcons(
color: AppColor.iconColor2,
text: '32min',
icon: FontAwesomeIcons.clock),
],
),
],
),
),
),
),
],
);
}
}
I think the carousel slider package provides the functionality you need. The package has an example, which exactly describes your issue.
you should try out https://api.flutter.dev/flutter/widgets/ListWheelScrollView-class.html
and for your layout, you can use rotate widget for the horizontal view and of course
you to use rotate widget on the child of the list too.
Save the current page and adjust the content based on that. Like below the current page, _currentPage == index, has smaller margins.
final _pageController = PageController(viewportFraction: 0.8);
int _currentPage = 0;
...
PageView.builder(
controller: _pageController,
itemCount: 5,
itemBuilder: (_, index) =>
Container(
margin: _currentPage == index
? const EdgeInsets.symmetric(vertical: 16)
: const EdgeInsets.symmetric(vertical: 64),
child: Image.network(
'https://picsum.photos/1080/1920?index=$index',
fit: BoxFit.cover,
loadingBuilder: (_, child, loadingProgress) {
if (loadingProgress == null) return child;
return const Center(child: CircularProgressIndicator());
}
)
),
onPageChanged: (page){
setState(() {
_currentPage = page;
});
},
)
)

it's possible to make listview in expand and fill parent without overflow?

it's possible to make listview in expand and fill the container without overflow the container, and shrink when listview is short of content without declare manual min or max height?
Code
Flexible(
fit: FlexFit.loose,
child: Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(kBoxRadius),
boxShadow: [kBoxShadow]),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
DText(
"Aug 2021",
size: 12,
weight: FontWeight.bold,
),
SizedBox(height: 10),
Row(
children: dates,
),
SizedBox(height: 15),
Container(
height: 1,
color: Color(0xFFE7E7E7),
),
Container(
constraints:
BoxConstraints(minHeight: 0, maxHeight: 600),
child: ListView.separated(
shrinkWrap: true,
itemBuilder: (context, index) {
return DText("Asd");
},
separatorBuilder: (_, __) {
return SizedBox(height: 10);
},
itemCount: 20,
),
)
],
),
),
)
Expectation
when the content is big
because i set manually max height.
Yes, it is possible using shrinkWrap: true. The code will be something like below,
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
color: Colors.red,
child: ListView(
shrinkWrap: true,
children: <Widget>[
ListTile(title: Text('Apple')),
ListTile(title: Text('Orange')),
ListTile(title: Text('Banana')),
],
),
),
),
),
);
}
}

flutter widget hides behind keyboard when it opens

I am trying to create a chat screen with text field at the bottom and whenever it is clicked the keyboard comes up and the textfield should be on top of the keyboard but my own isn't doing what it's supposed to do. I have checked other similar questions and answers on google, stackoverflow and github but it still stays the maybe because in mine am using constraints: BoxConstraints(maxHeight: 160), which might be what is causing it but i don't really know
This my code
class _ChatSectionState
extends State<ChatSectionState> {
List<File> images = List<File>();
getMultiFile() async {
await pickFileFromMobile("multi").then((value) {
if (value != null) {
value.paths.forEach((element) {
images.add(File(element));
});
// images = value.paths.map((path) => File(path)).toList();
}
});
setState(() {});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(...,
body: Container(
height: double.infinity,
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(bottom: 50),
child: Container(
child: ListView.builder(
itemCount: 10,
reverse: true,
shrinkWrap: true,
physics: ScrollPhysics(),
itemBuilder: (ctx, idx) {...
///...
),
),
),
///This is the part that hides behide the keyboard when it appears which i want to show on top
Align(
alignment: Alignment.bottomCenter,
child: Container(
decoration: BoxDecoration(
color: white,
border: Border(
top: BorderSide(
color: grey[400],
width: .7,
),
bottom: BorderSide(
color: grey[400],
width: .7,
)),
),
constraints: BoxConstraints(maxHeight: 160), //This is the box contraints
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
(images.length < 1)
? SizedBox(height: 0)
: Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
physics: ScrollPhysics(),
padding: EdgeInsets.symmetric(
vertical: 7, horizontal: 10),
itemCount: images.length,
itemBuilder: (ctx, idx) {
return Container(
///... This is to show a image from file width a height of 100
);
},
),
),
Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: grey[300],
width: .5,
)),
),
child: Row(children: [
Container(
margin: new EdgeInsets.symmetric(horizontal: 8.0),
child: new IconButton(
icon: new Icon(Icons.image),
onPressed: () => getMultiFile(),
color: primary,
),
),
Flexible(
child: Container(
child: TextFormField(
//controller: messageEditingController,
style: TextStyle(color: nBlack, fontSize: 15.0),
decoration: InputDecoration.collapsed(
hintText: 'Type a message',
hintStyle: TextStyle(color: grey),
),
onFieldSubmitted: (value) {},
),
),
),
Container(
margin: new EdgeInsets.symmetric(horizontal: 8.0),
child: new IconButton(
icon: new Icon(Icons.send),
onPressed: () {},
color: primary,
),
),
]),
),
],
),
),
)
],
),
),
resizeToAvoidBottomInset: false,
));
}
}
Please how can I make it work cause i have checked different pages still does give me what i want. I also tried this [answer][1]
[1]: https://stackoverflow.com/a/49715952/14650702 which worked but the animation was terrible
You can change resizeToAvoidBottomInset: ture, for scaffold.
it will shrink the whole scaffold when keyboard is opened.
I use another way. resizeToAvoidBottomInset: true and do some changes for lifting widgets top of keyboard.
bottom = MediaQuery.of(context).viewInsets.bottom;
Scaffold(
resizeToAvoidBottomInset: ture,
body: SingleChildScrollView(
reverse:true,
child: Padding(
padding: EdgeInsets.only(bottom: bottom),
child: ...
)));
if you decrease space from keyboard to last widget use MediaQuery.of(context).viewInsets.bottom/2 e.x.

Unable to set dynamic height for a Column involving ListView.builder() flutter

I have the following code where I'm trying to make a column inside which is a container containing title, and another container containing a list of items, that is scrollable horizontally. But I get the following runtime error - "
The following assertion was thrown during performResize():
Horizontal viewport was given unbounded height.
Viewports expand in the cross axis to fill their container and constrain their children to match their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of vertical space in which to expand."
Widget horizontalSlider(MediaQueryData mediaQuery){
final List<String> entries = <String>['A', 'B', 'C','D','E'];
return Container(
padding: EdgeInsets.all(0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(left:16),
child: Text("Home",style: TextStyle(fontSize: 36, fontWeight: FontWeight.bold),)
),
Container(
child: ListView.builder(
padding: EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index){
return Column(
children: <Widget>[
Container(
height: mediaQuery.size.height/3,
margin: EdgeInsets.all(8),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/$index.jpg'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(18),
boxShadow: [BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 4,
blurRadius: 4,
),],
),
width: mediaQuery.size.width/1.5,
),
Text("Item ${entries[index]}",style: TextStyle(fontSize: 18),),
],
);
},
scrollDirection: Axis.horizontal,
),
)],
),
);
}
What I expect from this is a heading (i.e. the first container inside the first column), an image of height equal to one-third of screen height and a Text widget at the end. But why do I get the error I cannot understand.
Finally I found the answer from this thread https://github.com/flutter/flutter/issues/18341. I have to replace the second Container with Expanded and it works well. Updated Code
Widget horizontalSlider(MediaQueryData mediaQuery){
final List<String> entries = <String>['A', 'B', 'C','D','E'];
return Container(
padding: EdgeInsets.all(0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(left:16),
child: Text("Home",style: TextStyle(fontSize: 36, fontWeight: FontWeight.bold),)
),
Expanded(
child: ListView.builder(
padding: EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index){
return Column(
children: <Widget>[
Container(
height: mediaQuery.size.height/3.5,
margin: EdgeInsets.all(8),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/$index.jpg'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(18),
boxShadow: [BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 4,
blurRadius: 4,
),],
),
width: mediaQuery.size.width/1.5,
),
Text("Item ${entries[index]}",style: TextStyle(fontSize: 18),),
],
);
},
scrollDirection: Axis.horizontal,
),
)],
),
);
}