How to display a text at the bottom left of the Image - flutter

I want to display a text at the bottom left if the image to be like as the below figure:
and this the below code is related:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/city.dart';
class ProvinceItem extends StatelessWidget {
#override
Widget build(BuildContext context) {
final city = Provider.of<City>(context, listen: false);
// final cart = Provider.of<Cart>(context, listen: false);
return Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
splashColor: Colors.transparent,
onTap: () => {},
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.withOpacity(0.6),
offset: const Offset(2.5, 2.5),
blurRadius: 16,
),
],
),
margin: EdgeInsets.all(2),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
),
child: Image.asset(
city.cityImage,
fit: BoxFit.cover,
),
),
),
),
);
}
}
I have just create a list of Grid widget and as every list of grid item have a grid item just shown like the previous code...
as I need the best suggestion for this Grid item as it only contains just an image and a text with some of shadows..

Stack widget will do the trick for you.
Stack(
children: <Widget>[
InkWell(
splashColor: Colors.transparent,
onTap: () => {},
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.withOpacity(0.6),
offset: const Offset(2.5, 2.5),
blurRadius: 16,
),
],
),
margin: EdgeInsets.all(2),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
bottomLeft: Radius.circular(15),
bottomRight: Radius.circular(15),
),
child: Image.asset(
city.cityImage,
fit: BoxFit.cover,
),
),
),
),
Container(
margin: EdgeInsets.only(left: 20, bottom: 20),
child: Align(
alignment: Alignment.bottomLeft,
child: Text(
'Text',,
style: TextStyle(color: Colors.white, fontSize: 20),
)),
),
],
),

Related

How to remove divider line between ddrawer and the list

How to remove divider line between ddrawer and the list?
I have next code:
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: [
const DrawerHeader(
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(40),
bottomRight: Radius.circular(40),
),
),
child: Text('Settings'),
),
ListTile(
leading: const Icon(Icons.settings),
title: const Text("Blue Print"),
),
],
),
);
that gives next drawer:
use container instead of drawer header widget and give decoration accordingly ,
Container(
width: MediaQuery.of(context).size.width,
height: 100,
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(40),
bottomRight: Radius.circular(40),
)),
child: Text('Settings',).paddingSymmetric(vertical: 20, horizontal: 20))
You can try this code for your Ui:
But one issue is bottom edge is not perfect circular but bottom Divider gone.
ClipRRect(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(50),
bottomRight: Radius.circular(50),
),
child: DrawerHeader(
decoration: BoxDecoration(
color: Colors.blueGrey,
),
child: Text('Settings'),
),
),
alternative solution:
Drawer(
child: ListView(
children: [
Container(
height: 200,
padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
child: Align(
alignment: Alignment.bottomLeft,
child: Text(
'Settings',
style: TextStyle(fontSize: 22),
)),
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(40),
bottomRight: Radius.circular(40),
),
),
),
ListTile(
leading: const Icon(Icons.settings),
title: const Text("Blue Print"),
),
],
),
)

Flutter: How can I add a box shadow to this widget?

I am trying to add a box shadow over a widget that displays an image. Whenever I include the box-shadow within the parent container, the shadow is only shown on the container which is stacked behind the child image. How can I have the shadow be displayed for the child image?
import 'package:flutter/material.dart';
import 'package:flutter_course_app_4/pages/nft_post.dart';
class NFTIconTemplate extends StatelessWidget {
final String NFTImg;
NFTIconTemplate({required this.NFTImg});
#override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
child: InkWell(
child: Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black54,
offset: Offset(4.0, 4.0),
blurRadius: 15.0,
spreadRadius: 1.0),
],
color: Colors.grey[800],
),
child: Column(
children: [
Image.network(
NFTImg,
width: 120,
height: 160,
fit: BoxFit.cover,
),
],
),
),
onTap: () {
print('Clicked NFT Icon');
Navigator.push(
context, MaterialPageRoute(builder: (context) => nftPost()));
},
),
),
);
}
}
Try this code to get extra shade to your code,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
bottomLeft: Radius.circular(12),
bottomRight: Radius.circular(12)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.6),
spreadRadius: 8,
blurRadius: 6,
offset: Offset(0, 4),
),
],
),

How do I automatically scale images in flutter to fit every resolution without overflow and scrolling?

I'm new and my English is pretty bad. Please answer easy to understand...
I already tried using the AspectRatio Widget but it, combined with a Center widget, moved my buttons in the center. Apart from that it worked but the buttons really need to stick to the side. This is my code so far:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'main.dart';
import 'contentData.dart';
import 'package:swipedetector/swipedetector.dart';
AppBrain contentData = AppBrain();
class SwipePage extends StatefulWidget {
SwipePage({Key key, this.title}) : super(key: key);
final String title;
#override
_SwipePage createState() => _SwipePage();
}
class _SwipePage extends State<SwipePage> {
#override
Widget build(BuildContext context) {
return SwipeDetector(
swipeConfiguration: SwipeConfiguration(
horizontalSwipeMaxHeightThreshold: 80.0,
horizontalSwipeMinDisplacement: 30.0,
horizontalSwipeMinVelocity: 150.0),
onSwipeLeft: () {
Navigator.of(context).push(
toInformationPage(),
);
},
child: Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 20, bottom: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.asset(
AppBrain().getImageAdress(),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 20.0, bottom: 20),
child: Divider(
color: Colors.grey,
height: 20,
thickness: 2,
indent: 120,
endIndent: 120,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
decoration: BoxDecoration(
color: buttonColor,
borderRadius: BorderRadius.only(
topRight: Radius.circular(50),
bottomRight: Radius.circular(50),
),
),
child: MaterialButton(
height: 60,
onPressed: () {},
textColor: red,
child: Icon(
Icons.close,
size: 45,
),
),
),
Container(
width: 120,
),
Container(
decoration: BoxDecoration(
color: buttonColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50),
),
),
child: MaterialButton(
height: 60,
onPressed: () {
Navigator.of(context).push(
toInformationPage(),
);
},
textColor: green,
child: Icon(
Icons.check,
size: 45,
),
),
),
],
),
)
],
),
),
),
),
);
}
}
This is what it looks like now:
https://imgur.com/a/2kgpJ6A
This is what it should look like across all aspect-ratios and resolutions (the image should just scale down..):
https://imgur.com/FBNlpDa
Looking at your code you have at least two different problems.
Setting the correct image fit - You can use BoxFit.contain in Image.asset(fit: boxFit.contain, .... ) to make sure it is resized to be contained inside it's parent.
You have a Column and want the first child to take all the available width. Hence you should nest it inside Expanded widget.
ie. structurally something like:
Column(
children: [
Expanded(
// your image goes here which will take as much height as possible.
child: Image.asset('asset', fit: BoxFit.contain),
),
Container(
// your button bar which takes up the rest of the height
child: MaterialButton( ... ),
),
],
);
I left out quite a bit, but i hope you get the gist.
I think I fixed it myself with the help of Herbert, thanks :). I wrapped the Container containing my image in an Expanded widget and set a flex value of 3.
This is my new code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'main.dart';
import 'contentData.dart';
import 'package:swipedetector/swipedetector.dart';
AppBrain contentData = AppBrain();
class SwipePage extends StatefulWidget {
SwipePage({Key key, this.title}) : super(key: key);
final String title;
#override
_SwipePage createState() => _SwipePage();
}
class _SwipePage extends State<SwipePage> {
#override
Widget build(BuildContext context) {
return SwipeDetector(
swipeConfiguration: SwipeConfiguration(
horizontalSwipeMaxHeightThreshold: 80.0,
horizontalSwipeMinDisplacement: 30.0,
horizontalSwipeMinVelocity: 150.0),
onSwipeLeft: () {
Navigator.of(context).push(
toInformationPage(),
);
},
child: Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
flex: 4,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.asset(
AppBrain().getImageAdress(),
fit: BoxFit.contain,
),
),
margin: EdgeInsets.fromLTRB(25, 25, 25, 0),
),
),
Padding(
padding: const EdgeInsets.only(
top: 20.0,
),
child: Divider(
color: Colors.grey,
height: 20,
thickness: 2,
indent: 120,
endIndent: 120,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
decoration: BoxDecoration(
color: buttonColor,
borderRadius: BorderRadius.only(
topRight: Radius.circular(50),
bottomRight: Radius.circular(50),
),
),
child: MaterialButton(
height: 60,
onPressed: () {},
textColor: red,
child: Icon(
Icons.close,
size: 45,
),
),
),
Container(
width: 120,
),
Container(
decoration: BoxDecoration(
color: buttonColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
bottomLeft: Radius.circular(50),
),
),
child: MaterialButton(
height: 60,
onPressed: () {
Navigator.of(context).push(
toInformationPage(),
);
},
textColor: green,
child: Icon(
Icons.check,
size: 45,
),
),
),
],
),
)
],
),
),
),
);
}
}
You can try using FittedBox widget too.

Best way to add a shadow and colored border to ClipRRect using flutter

I have a simple ClipRRect widget as the below one:
#override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: GridTile(
child: Image.network(
imageUrl,
fit: BoxFit.cover,
),
footer: GridTileBar(
backgroundColor: Colors.black87,
leading: IconButton(
icon: Icon(Icons.favorite),
color: Theme.of(context).accentColor,
onPressed: () {},
),
title: Text(
title,
textAlign: TextAlign.center,
),
trailing: IconButton(
icon: Icon(Icons.shopping_cart),
onPressed: () {},
color: Theme.of(context).accentColor,
),
),
),
);
}
I tried to add a shadow by wrapping this widget with another Card widget to add a shadow with an elevation as the below code:
#override
Widget build(BuildContext context) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 5,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: GridTile(
child: Image.network(
imageUrl,
fit: BoxFit.cover,
),
footer: GridTileBar(
backgroundColor: Colors.black87,
leading: IconButton(
icon: Icon(Icons.favorite),
color: Theme.of(context).accentColor,
onPressed: () {},
),
title: Text(
title,
textAlign: TextAlign.center,
),
trailing: IconButton(
icon: Icon(Icons.shopping_cart),
onPressed: () {},
color: Theme.of(context).accentColor,
),
),
),
),
);
}
but I think it's not logical at all because it shows the grid item a bit smaller, and also I need add a border in this grid..
I hope this would be clear enough..
you can create your widget to take in a shadow and border colors as follows
since ClipRRect cant take in shadow or border color we use a container
clipRRect constructor
ClipRRect({Key key, BorderRadius borderRadius: BorderRadius.zero, CustomClipper<RRect> clipper, Clip clipBehavior: Clip.antiAlias, Widget child})
.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
height: 200,
width: 200,
child: Card(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(10),
topRight: Radius.circular(10)),
side: BorderSide(width: 2, color: Colors.green)),
child: Center(
child: Icon(
Icons.movie,
size: 150.0,
),
),
),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.white54,
blurRadius: 5.0,
offset: Offset(0, 10),
spreadRadius: 0.5,
),
],
borderRadius: BorderRadius.circular(12),
),
);
}
}
Here's another solution which worked for me.
Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: SizedBox(
child: ImageWidget(imageUrl),
width: 100,
height: 100,
),
),
width: 100,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.15),
blurRadius: 8,
spreadRadius: 6,
offset: const Offset(0, 0),
),
],
),
)
I implemented it like below
Stack(alignment: Alignment.center, children: [
Container(
width: DeviceUtils.getScaledHeight(context, 0.072),
height: DeviceUtils.getScaledHeight(context, 0.072),
decoration: BoxDecoration(
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.white54,
blurRadius: 5.0,
offset: Offset(0, 10),
spreadRadius: 0.5,
),
],
),
),
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: ImageFromURL(
url: "https://i.pinimg.com/originals/63/81/a7/6381a77565b51a541d0d85cb145e7d94.jpg",
width: DeviceUtils.getScaledHeight(context, 0.07),
height: DeviceUtils.getScaledHeight(context, 0.07)),
),
])

Border container and card

I've the following code:
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
child: InkWell(
onTap: () {
....
},
child: Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: Theme.of(context).primaryColor,
width: 3.0,
)),
//borderRadius: BorderRadius.only(topLeft: const Radius.circular(5.0), topRight: const Radius.circular(5.0)),
),
height: 133,
child: ...,
),
));
}
The problem is that I am trying to set a color on the top border and assign a border radius of 5. As far as I am aware, I can't assign a color to the top border in the card. You have to set it all the way around. But you can do this on the container. The problem is that adding a radius to the Container makes the content inside it disappear.
That's an interesting mechanic... Though not ideal, I suppose you could wrap your child with a Column and make your own custom border element, so it doesn't clash with your content.
Something like this:
class MyTopBorder extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(5.0),
topRight: const Radius.circular(5.0),
),
color: Theme.of(context).primaryColor,
),
height: 3.0,
);
}
}
and then add it to your Card:
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
child: InkWell(
onTap: () {
// ...
},
child: Column(
children: <Widget>[
MyTopBorder(),
Container(
height: 133,
child: Text("..."),
),
],
),
),
),