Related
I currently have a page with an image like this, but I want to add an svg image to the button section at the bottom as in the second image. How can I do it?
İmages
My Code :
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'URL Shortener',
theme: ThemeData(
primarySwatch: Colors.purple,
),
home: StartPage(),
);
}
}
class StartPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
body: Center(
child: ListView(
children: [
Center(
child: Text(
"Shortly",
style: TextStyle(
fontSize: 40,
height: 2.0,
color: Color.fromRGBO(53, 50, 62, 10),
fontWeight: FontWeight.bold),
),
),
SvgPicture.asset(
'assets/illustration.svg',
),
Center(
child: Text(
"Let's get started!",
style: TextStyle(
fontSize: 20,
color: Color.fromRGBO(53, 50, 62, 10),
fontWeight: FontWeight.bold),
),
),
Center(
child: SizedBox(
width: 200,
height: 60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Paste your first link into the field to shorten it",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
color: Color.fromRGBO(76, 74, 85, 10),
fontWeight: FontWeight.bold)),
),
),
),
Center(
child: SizedBox(
width: 300,
height: 40,
child: TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
fillColor: Colors.white,
filled: true,
hintText: 'Shorten a link here ...'),
),
),
),
Center(
child: SizedBox(
width: 300,
child: ElevatedButton(
onPressed: () {
print("Button Click");
},
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(60, 40),
),
child: Text('SHORTEN IT!'),
),
),
)
],
),
));
}
}
Hello, I currently have a page with an image like this, but I want to add an svg image to the button section at the bottom as in the second image. How can I do it?
Demo Widget
class StartPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
body: ListView(
children: [
Center(
child: Text(
"Shortly",
style: TextStyle(
fontSize: 40,
height: 2.0,
color: Color.fromRGBO(53, 50, 62, 10),
fontWeight: FontWeight.bold),
),
),
// SvgPicture.asset(
// 'assets/illustration.svg',
// ),
Container(
height: 200,
color: Colors.deepPurple.withOpacity(.3),
child: Text("SVG assets here"),
),
Center(
child: Text(
"Let's get started!",
style: TextStyle(
fontSize: 20,
color: Color.fromRGBO(53, 50, 62, 10),
fontWeight: FontWeight.bold),
),
),
Center(
child: SizedBox(
width: 200,
height: 60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Paste your first link into the field to shorten it",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
color: Color.fromRGBO(76, 74, 85, 10),
fontWeight: FontWeight.bold)),
),
),
),
SizedBox(
/// bottombackground height
height: 220,
child: Stack(
alignment: Alignment.center,
children: [
/// background svg asset
Container(
color: Colors.deepOrange.withOpacity(.4),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 300,
height: 40,
child: TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
fillColor: Colors.white,
filled: true,
hintText: 'Shorten a link here ...'),
),
),
/// a little space between buttons
SizedBox(
height: 10,
),
SizedBox(
width: 300,
child: ElevatedButton(
onPressed: () {
print("Button Click");
},
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(60, 40),
),
child: Text('SHORTEN IT!'),
),
),
],
),
],
),
),
],
),
);
}
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
body: Center(
child: Container(
height:MediaQuery.of(context).size.height,
width:MediaQuery.of(context).size.width,
child: Stack(
children: [
SvgPicture.asset(
"assets/a.svg",
fit: BoxFit.fill,
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween ,
children: [
Center(
child: Container(
margin: EdgeInsets.only(top:20.0),
child: Text(
"Shortly",
style: TextStyle(
fontSize: 40,
height: 2.0,
color: Color.fromRGBO(53, 50, 62, 10),
fontWeight: FontWeight.bold),
),
),
),
Column(
children: [
Center(
child: Container(
margin: EdgeInsets.only(top:200.0),
child: Text(
"Let's get started!",
style: TextStyle(
fontSize: 20,
color: Color.fromRGBO(53, 50, 62, 10),
fontWeight: FontWeight.bold),
),
),
),
Center(
child: SizedBox(
width: 200,
height: 60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Paste your first link into the field to shorten it",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
color: Color.fromRGBO(76, 74, 85, 10),
fontWeight: FontWeight.bold)),
),
),
),
],
),
Container(
height: 150.0,
color: Colors.purple,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Container(
width: 300,
height: 40,
child: TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
fillColor: Colors.white,
filled: true,
hintText: 'Shorten a link here ...'),
),
),
),
Center(
child: SizedBox(
width: 300,
child: ElevatedButton(
onPressed: () {
print("Button Click");
},
style: ElevatedButton.styleFrom(
primary: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
minimumSize: Size(60, 40),
),
child: Text('SHORTEN IT!'),
),
),
),
],
),
)
],
),
],
),
),
));
}
I'm trying to place an image a little bit outside of container i used stack and positioned to position the image a little bit outside of container from top, but the part of image that looks like it's gone this is how it looks
and this is how i want it to look like
and this is my code
Column(
children: [
Stack(
fit: StackFit.loose,
clipBehavior: Clip.hardEdge,
children: [
Container(
height: 151.0,
width: 122.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xffFFF0E5),
Color(0xffdeddc2),
Color(0xffa9ceb1),
Color(0xff68bdb9),
Color(0xff30a6ca)
],
),
boxShadow: [
BoxShadow(
color:
Color.fromARGB(255, 234, 246, 250),
spreadRadius: 8,
blurRadius: 7,
offset: Offset(0, 6),
),
],
border: Border.all(
width: 4,
color: Colors.yellow,
),
),
child: Positioned(
top: 75.0,
child: Container(
child: Image.asset(
'assets/images/watch-gt2-listimage-Matte-Black.png',
height: 120.0,
width: 125.0,
),
),
),
),
],
),
],
),
You have to change clipBehavior: Clip.none in all of its parent widgets like Stack and Container.
So I have this code that loads images from assets, correctly:
ClipRRect getUserCard(int index) {
double screenWidth = MediaQuery.of(context).size.width;
double screenHeight = MediaQuery.of(context).size.height;
return ClipRRect(
borderRadius: BorderRadius.circular(25),
child: Stack(
children: [
//IMAGE (and Name Overlay)
Container(
width: screenWidth,
height: screenHeight,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(lstUsers[index]["imageUrl"][0]),
fit: BoxFit.cover),
),
//NAME OVERLAY
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
//NAME AND AGE
Container(
//alignment: Alignment.center,
height: 80,
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.6),
//borderRadius: BorderRadius.circular(15),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
lstUsers[index]["name"] + ", ",
style: const TextStyle(
color: Colors.white,
fontSize: 24,
),
textAlign: TextAlign.center,
),
Text(
lstUsers[index]["age"],
style: const TextStyle(
color: Colors.white,
fontSize: 20,
),
textAlign: TextAlign.center,
),
],
),
Text(
lstUsers[index]["profession"],
style: const TextStyle(
color: Colors.white,
fontStyle: FontStyle.italic,
fontSize: 18,
),
textAlign: TextAlign.center,
),
],
),
),
const Divider(),
//SWIPE BUTTONS
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
FloatingActionButton(
child: const Icon(
Icons.close_outlined,
color: Colors.black,
size: 32,
),
backgroundColor: Colors.white,
onPressed: () {
setState(() {
cardController.triggerLeft();
});
},
),
const SizedBox(
width: 25,
),
FloatingActionButton(
child: const Icon(
Icons.favorite_border_outlined,
color: Colors.black,
size: 32,
),
backgroundColor: Colors.white,
onPressed: () {
setState(() {
cardController.triggerRight();
});
},
),
]),
const Divider(),
],
),
//),
),
// ),
],
),
);
}
However, this causes the app to crash every few minutes. After googling I realized its because I am loading the images in the main thread. What is the right way to load the images. Do I need to use async / Future here. If so, how?
List lstUsers = [
{
"id": "p1",
"name": "John Doe",
"age": "44",
"imageUrl": [
"assets/images/anastasia-vityukova-unsplash-blackandwhiteimage.png",
"assets/images/anastasia-vityukova-unsplash.png",
],
"profession": "Financial Consultant"
},
{
"id": "p2",
"name": "John Doe 2",
"age": "42",
"imageUrl": [
"assets/images/good-faces-hiba-unsplash-blackandwhiteimage.png",
"assets/images/good-faces-hiba-unsplash.jpg",
],
"profession": "Financial Consultant"
}
];
EDIT: It wasn't crashing till I used only one image url; meaning the image url was just another key like the other properties. Now that I have included multiple images, it crashes.
Try this AssetImage alternate and see if the problem persists,
...
//IMAGE (and Name Overlay)
Container(
width: screenWidth,
height: screenHeight,
child: Image.asset(
lstUsers[index]["imageUrl"][0],
fit: BoxFit.cover,
),
),
...
You need to remove assets from assets/images/anastasia-vityukova-unsplash-blackandwhiteimage.png,
Like images/anastasia-vityukova-unsplash-blackandwhiteimage.png.
Demo output with structure, Flutter 2.5.0
Here are details about assets-and-images.
Does it solve the issue?
Turns out it was a problem with the emulator; I ran it on a device and it was working fine.
Is there any plugin in Flutter which could achieve something like the profile picture preview of persons who liked the picture on Instagram?
There is no plugin but you can make a custom one using circle avatars(with white border) in a stack.
class CustomAvatars extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
width: 80,
height: 40,
color: Colors.white,
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.centerRight,
child: CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundColor: Colors.red,
child: Image.asset('assets\image'), // Provide your custom image
),
),
),
Align(
alignment: Alignment.center,
child: CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundColor: Colors.red,
child: Image.asset('assets\image'), // Provide your custom image
),
),
),
Align(
alignment: Alignment.centerLeft,
child: CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundColor: Colors.red,
child: Image.asset('assets\image'), // Provide your custom image
),
),
),
],
),
);
}
}
Or you can use Align inside of ListView(); widget
Widget _stackedHeads() => Container(
width: double.infinity,
height: 100,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 4,
itemBuilder: (context, index) {
return Align(
widthFactor: 0.6,
child: CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundImage: NetworkImage(
'https://www.jessleewong.com/wp-content/uploads/2019/12/jessleewong_20191109_3.jpg'), // Provide your custom image
),
),
);
}));
cames in handy when your content is dynamic, in that code in Align(); widget property widthFactor: determines how much in horizontal they should overlap.
You could try my package (signed_spacing_flex). It's exactly the same as a normal Row (or Column and Flex). But it also lets you set negative spacing which causes its children to overlap. You can also set which children should be on top when they overlap.
In your case it would be something like:
const imageURL = "https://upload.wikimedia.org/wikipedia/commons/thumb/9/95/Instagram_logo_2022.svg/150px-Instagram_logo_2022.svg.png";
SignedSpacingRow(
spacing: -16.0,
stackingOrder: StackingOrder.firstOnTop,
children: const [
CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundImage: NetworkImage(imageURL),
),
),
CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundImage: NetworkImage(imageURL),
),
),
CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundImage: NetworkImage(imageURL),
),
),
],
),
It also works with expanded children if you need.
There is no plugin but you can make a custom one using circle avatars and positioned in a stack.
import 'package:flutter/material.dart';
class CustomAvatar extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
width: 80,
height: 40,
color: Colors.white,
child: Stack(
children: <Widget>[
Positioned(
left: 0,
child: CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundColor: Colors.red,
child: Image.asset('assets\image'), // Provide your custom image
),
),
),
Positioned(
left: 8,
child: CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundColor: Colors.red,
child: Image.asset('assets\image'), // Provide your custom image
),
),
),
Positioned(
left: 16,
child: CircleAvatar(
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 18,
backgroundColor: Colors.red,
child: Image.asset('assets\image'), // Provide your custom image
),
),
),
],
),
);
}
}
I have often found really quick and very competent help here. And hope you can help me again.
I have had an error message for three days, which I cannot get solved.
I explained the problem to you in a small video.
The link to the video is: "https://drive.google.com/file/d/1T9uOnEaNp5W6_kcO6eV9o64Fp3sRkB3f/view?usp=sharing"
I really hope you see the mistake I don't see!
This is the code of the Foodcard, which according to Flutter should cause the error:
The method '-' was called on null.
Receiver: null
Tried calling: -(30.0)
The relevant error-causing widget was:
FoodCard file:///C:/Users/stefa/AndroidStudioProjects/cronum_app_web%20-%20Kopie/lib/Components/ProviderComponents.dart:298:9
FoodCard:
class FoodCard extends StatelessWidget {
FoodCard({
#required this.description,
#required this.imagePath,
#required this.price,
#required this.foodName,
#required this.foodItem,
#required this.increaseCallback,
#required this.decreaseCallback,
this.count = 0,
});
final double radius = 40;
static double listViewHeight;
final double margin = 15;
final double containerHeight = 130;
final int count;
final String imagePath;
final String foodName;
final String price;
final String description;
final FoodItem foodItem;
final Function increaseCallback;
final Function decreaseCallback;
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 10, vertical: margin),
width: 220,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(radius),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.topRight,
colors: ([
gradientColor1.withOpacity(opacityOfHeader),
primaryColor.withOpacity(opacityOfHeader),
gradientColor2.withOpacity(opacityOfHeader),
]),
),
boxShadow: [
BoxShadow(
blurRadius: 8,
color: Colors.black.withOpacity(0.3),
offset: Offset(5, 5),
),
],
color: Colors.white,
),
child: Column(
children: <Widget>[
Stack(
alignment: Alignment.center,
children: <Widget>[
Column(
children: <Widget>[
SizedBox(
height: listViewHeight - margin * 2 - containerHeight,
),
Container(
height: containerHeight,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(radius),
topRight: Radius.circular(radius),
bottomLeft: Radius.circular(radius),
bottomRight: Radius.circular(radius),
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
offset: Offset(0, -5),
blurRadius: 8)
],
color: Colors.white),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 40),
child: Center(
child: Text(
foodName,
style: TextStyle(
color: Colors.black,
fontSize: 17,
fontWeight: FontWeight.w900,
),
),
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(
foodItem: foodItem,
increaseCount: increaseCallback,
decreaseCount: decreaseCallback,
),
),
);
},
child: Container(
height: 30,
width: 80,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
offset: Offset(5, 5),
color: Colors.black.withOpacity(0.3),
blurRadius: 8)
],
color: buttonColor,
borderRadius: BorderRadius.circular(25),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 7, vertical: 5),
child: Center(
child: Text(
'Details',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
),
),
),
Container(
color: Colors.grey.withOpacity(0.5),
height: 25,
width: 1,
),
Container(
height: 30,
width: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
color: buttonColor,
boxShadow: [
BoxShadow(
blurRadius: 8,
color: Colors.black.withOpacity(0.3),
offset: Offset(5, 5),
),
],
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: <Widget>[
InkWell(
onTap: decreaseCallback,
child: Container(
height: 22,
width: 22,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5),
color: buttonColor,
),
child: Center(
child: Icon(
Icons.remove,
color: Colors.white,
size: 22,
),
),
),
),
Text(
count.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w900,
),
),
InkWell(
onTap: increaseCallback,
child: Container(
height: 22,
width: 22,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(15),
color: Colors.white,
),
child: Center(
child: Icon(
Icons.add,
color: buttonColor,
size: 22,
),
),
),
),
],
),
),
],
),
),
],
),
),
],
),
Positioned(
top: 30,
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(
foodItem: foodItem,
increaseCount: increaseCallback,
decreaseCount: decreaseCallback,
),
),
);
},
child: Image(
height: listViewHeight / 2,
width: listViewHeight / 2,
image: AssetImage(imagePath),
),
),
),
],
)
],
),
);
}
If it is not because of the FoodCard, the function with which I create the list of Foodcards could also be the problem.
I am amazed by the error message because it is so extremely non-specific. Before I automated the creation of the list, everything worked wonderfully.
List<Widget> buildEntdeckenCards() {
List<Widget> foodCardList = [];
for (FoodItem foodItem in top10) {
print(foodItem.foodName);
foodCardList.add(
FoodCard(
description: foodItem.description,
foodName: foodItem.foodName,
foodItem: foodItem,
price: foodItem.price,
imagePath: foodItem.imagePath,
decreaseCallback: () {
decreaseCount(foodItem);
},
increaseCallback: () {
increaseCount(foodItem);
},
),
);
}
return foodCardList;
}
I think your listViewHeight variable is null, and you are trying to use it in expression
SizedBox(height: listViewHeight - margin * 2 - containerHeight,),
I think that's why you see the following error The method '-' was called on null. Assign some value to listViewHeight before using it.