How to stack items on top of each other? - flutter

i'm trying make a widget like image below.
Mindset of me is stack item into listview. The items are stacked. But when nesting a stack into listview, the stack needs to be wrapped in a fixed widget. If you remove the listview, you cannot make it into the list as in the picture. First time there is nothing wrong to expect people to ignore.
I hope to get the answer. Thanks.
body: Container(
color: Colors.white,
width: double.infinity,
child: SingleChildScrollView(
child: Stack(
children: <Widget>[
Positioned(top: 10,child: card1(),),
Positioned(bottom: 10,child: card1(),),
],
),
),
),
Item
static Widget card1() {
return Card(
elevation: 0,
child: Container(
margin: EdgeInsets.only(top: 100),
width: double.infinity,
padding: EdgeInsets.only(top: 18, left: 18),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(offset: Offset(0, 8), blurRadius: 8, spreadRadius: 0),
],
),
child: Stack(
children: <Widget>[
Container(
width: 343,
height: 196,
child: SvgPicture.asset(
"assets/bg.svg",
),
),
Container(
padding: EdgeInsets.only(
top: 24,
left: 24,
),
child: Row(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10),
child: Text("Vietcombank"),
),
],
),
),
],
),
),
);
}

I created StackedListTile, you can try it (Demo here DartPad)
import 'package:flutter/material.dart';
class StackedListTile extends StatelessWidget {
final Color color;
final String title;
final ImageProvider iconImage;
const StackedListTile({
Key key,
#required this.color,
#required this.title,
#required this.iconImage,
}) : assert(color != null),
super(key: key);
#override
Widget build(BuildContext context) {
return SizedBox(
height: 90.0,
child: Stack(
children: <Widget>[
Container(
margin: const EdgeInsets.only(
left: 18.0,
top: 18.0,
right: 18.0,
),
padding: const EdgeInsets.only(
left: 25.0,
top: 25.0,
right: 25.0,
bottom: 10.0,
),
decoration: BoxDecoration(
color: color,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
),
),
child: Row(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.white,
child: Image(
image: iconImage,
fit: BoxFit.cover,
),
),
),
),
const SizedBox(width: 5.0),
Expanded(
child: Text(
title,
style: const TextStyle(
color: Colors.white,
letterSpacing: 1.0,
),
),
),
//TODO: Add other stuff here
const Icon(
Icons.arrow_forward_ios,
color: Colors.white,
size: 20.0,
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 4.0,
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Colors.transparent, Colors.black12],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
),
),
],
),
);
}
}
Usage:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: MainPage(),
debugShowCheckedModeBanner: false,
),
);
}
class MainPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Demo")),
body: ListView(
children: <Widget>[
StackedListTile(
title: "Techcombank1",
color: Colors.blue[600],
//iconImage: AssetImage("assets/images/1.png"), //TODO: Use this for asset images
iconImage: NetworkImage(
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQfo2BL_di4IK1AuHOS4y_16BatmqdkOlcB1JBjJK2zK9sUvZ2FUg&s",
),
),
StackedListTile(
title: "Techcombank2",
color: Colors.red[600],
iconImage: NetworkImage("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQNvzXsqFidC5YqNrKHEJGt1kyC99dJ_EWt_Bcc5dyy4rNGzFk8yQ&s"),
),
StackedListTile(
title: "Techcombank3",
color: Colors.green[600],
iconImage: NetworkImage("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQNvzXsqFidC5YqNrKHEJGt1kyC99dJ_EWt_Bcc5dyy4rNGzFk8yQ&s"),
),
for(int i =0; i<100; i++)
StackedListTile(
title: "Item_$i",
color: Colors.amber.withOpacity(1-(i%10)/10),
iconImage: NetworkImage("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQNvzXsqFidC5YqNrKHEJGt1kyC99dJ_EWt_Bcc5dyy4rNGzFk8yQ&s"),
),
],
),
);
}
}

Try to use SliverToBoxAdapter
body: return Container(
color: Colors.white,
width: double.infinity,
child: SingleChildScrollView(
child: SliverToBoxAdapter(
child: Stack(
children: <Widget>[
Positioned(
top: 10,
child: card1(),
),
Positioned(
bottom: 10,
child: card1(),
),
],
),
),
),
),

Related

How to set a separate value for each category to open related categories in flutter

Hello respected developers! I am trying to set separate category value for each category but now when I click on Pizza category it shows pizza, and when I click on other categories like Sandwich, Burger or anything else. it show the same value as it was designed in a widget. How to set category value for each category screen to have its own and related value. Please help me. here is a portion of my code that need to be fixed I can do it with a hard code but if I have more than 10 categories my code will be too long. Thank you very much and I really appreciate your help.
import 'package:flutter/material.dart';
import 'package:zar/screen/categories.dart';
class TopCard extends StatefulWidget {
const TopCard({Key? key}) : super(key: key);
#override
State<TopCard> createState() => _TopCardState();
}
// TOP CARD CLASS STARTS HERE
class CardItem {
final String urlImage;
final String title;
final String subTitle;
const CardItem({
required this.urlImage,
required this.title,
required this.subTitle,
});
}
// TOP CARD WIDGETS STARTS HERE
Widget topCard({
required CardItem item,
required BuildContext context,
}) =>
Container(
width: 150,
child: Column(
children: [
Expanded(
child: AspectRatio(
aspectRatio: 2 / 2,
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Material(
child: Ink.image(
image: NetworkImage(item.urlImage),
fit: BoxFit.cover,
child: InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Categories(
item: item,
),
),
),
),
),
),
),
),
),
const SizedBox(height: 4),
Text(
item.title,
style: const TextStyle(
color: Color(0xff5e35b1),
fontSize: 20,
fontWeight: FontWeight.bold),
),
Text(
item.subTitle,
style: const TextStyle(
color: Colors.redAccent,
),
),
],
),
);
class _TopCardState extends State<TopCard> {
// TOP CARD LIST VIEW STARTS HERE
List<CardItem> items = const [
CardItem(
urlImage:
'https://images.unsplash.com/photo-1542834369-f10ebf06d3e0?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80',
title: 'PIZZA',
subTitle: '\$20',
),
CardItem(
urlImage:
'https://images.unsplash.com/photo-1621852004158-f3bc188ace2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80',
title: 'SANDWICH',
subTitle: '\$7.99',
),
CardItem(
urlImage:
'https://images.unsplash.com/photo-1534938665420-4193effeacc4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=871&q=80',
title: 'FRIES',
subTitle: '\$2.99',
),
CardItem(
urlImage:
'https://images.unsplash.com/photo-1585238341710-4d3ff484184d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=804&q=80',
title: 'BURGER',
subTitle: '\$5.99',
),
];
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 20),
height: 150,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: 4,
separatorBuilder: (constext, _) => const SizedBox(width: 16),
itemBuilder: (context, index) => topCard(
context: context,
item: items[index],
),
),
);
}
}
This is my home screen category
This is my Category screen that shows Pizza categories.
And again this is my Category screen that shows the same Pizza categories. And I want this to be different.
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 20),
height: 150,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: 4,
separatorBuilder: (constext, _) => const SizedBox(width: 16),
itemBuilder: (context, index) => topCard(
context: context,
item: items[index],
),
),
);
}
Here is my category screen code:
import 'package:flutter/material.dart';
import 'package:zar/widgets/top_card.dart';
class Categories extends StatelessWidget {
final CardItem item;
const Categories({Key? key, required this.item}) : super(key: key);
#override
Widget build(BuildContext context) {
final double height = MediaQuery.of(context).size.height;
final double width = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
title: Text(item.title),
),
body: ListView(
children: [
Container(
height: 350,
width: double.infinity,
color: const Color(0xff673ab7),
child: Column(
children: [
AspectRatio(
aspectRatio: 3 / 2,
child: Image.network(item.urlImage),
),
Text(
item.title,
style: const TextStyle(
color: Colors.white,
fontSize: 25,
fontWeight: FontWeight.bold,
),
)
],
),
),
SizedBox(
height: height * 0.01,
),
Center(
child: Container(
height: 167,
child: Stack(
children: [
Positioned(
child: Material(
child: Container(
margin: const EdgeInsets.all(5),
height: 300,
width: width * 0.9,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: const Color(0xff5e35b1).withOpacity(0.3),
blurRadius: 6.0,
offset: const Offset(4, 8),
),
],
),
),
),
),
Positioned(
top: 6,
left: 5,
child: Card(
elevation: 10.0,
shadowColor: const Color(0xff5e35b1).withOpacity(0.3),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Container(
height: 150,
width: 150,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
image: const DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
"https://images.unsplash.com/photo-1625395005224-0fce68a3cdc8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=580&q=80"),
)),
),
),
),
Positioned(
top: 15,
left: 180,
child: Container(
height: 150,
width: 180,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Pizza",
style: TextStyle(
color: Color(0xff5e35b1),
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
Text(
"Italian Chees and Beef",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Divider(
color: Color(0xff5e35b1),
),
],
),
),
),
Positioned(
top: 120,
left: 180,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Rating",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Text("4.5"),
],
),
),
),
Positioned(
top: 120,
left: 350,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Price",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Text("\$20"),
],
),
),
),
],
),
),
),
SizedBox(
height: height * 0.01,
),
Center(
child: Container(
height: 167,
child: Stack(
children: [
Positioned(
child: Material(
child: Container(
margin: const EdgeInsets.all(5),
height: 300,
width: width * 0.9,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: const Color(0xff5e35b1).withOpacity(0.3),
blurRadius: 6.0,
offset: const Offset(4, 8),
),
],
),
),
),
),
Positioned(
top: 6,
left: 5,
child: Card(
elevation: 10.0,
shadowColor: const Color(0xff5e35b1).withOpacity(0.3),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Container(
height: 150,
width: 150,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
image: const DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
"https://images.unsplash.com/photo-1606502281004-f86cf1282af5?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=580&q=80"),
)),
),
),
),
Positioned(
top: 15,
left: 180,
child: Container(
height: 150,
width: 180,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Special Mini Pizza",
style: TextStyle(
color: Color(0xff5e35b1),
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
Text(
"American Pizza",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Divider(
color: Color(0xff5e35b1),
),
],
),
),
),
Positioned(
top: 120,
left: 180,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Rating",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Text("4.5"),
],
),
),
),
Positioned(
top: 120,
left: 350,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Price",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Text("\$9.99"),
],
),
),
),
],
),
),
),
SizedBox(
height: height * 0.01,
),
Center(
child: Container(
height: 167,
child: Stack(
children: [
Positioned(
child: Material(
child: Container(
margin: const EdgeInsets.all(5),
height: 300,
width: width * 0.9,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: const Color(0xff5e35b1).withOpacity(0.3),
blurRadius: 6.0,
offset: const Offset(4, 8),
),
],
),
),
),
),
Positioned(
top: 6,
left: 5,
child: Card(
elevation: 10.0,
shadowColor: const Color(0xff5e35b1).withOpacity(0.3),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Container(
height: 150,
width: 150,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
image: const DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
"https://images.unsplash.com/photo-1628840042765-356cda07504e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=580&q=80"),
)),
),
),
),
Positioned(
top: 15,
left: 180,
child: Container(
height: 150,
width: 180,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Paparoni Pizza",
style: TextStyle(
color: Color(0xff5e35b1),
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
Text(
"Maxcan Pizza",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Divider(
color: Color(0xff5e35b1),
),
],
),
),
),
Positioned(
top: 120,
left: 180,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Rating",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Text("4.5"),
],
),
),
),
Positioned(
top: 120,
left: 350,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Price",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Text("\$17.50"),
],
),
),
),
],
),
),
),
SizedBox(
height: height * 0.01,
),
Center(
child: Container(
height: 167,
child: Stack(
children: [
Positioned(
child: Material(
child: Container(
margin: const EdgeInsets.all(5),
height: 300,
width: width * 0.9,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: const Color(0xff5e35b1).withOpacity(0.3),
blurRadius: 6.0,
offset: const Offset(4, 8),
),
],
),
),
),
),
Positioned(
top: 6,
left: 5,
child: Card(
elevation: 10.0,
shadowColor: const Color(0xff5e35b1).withOpacity(0.3),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Container(
height: 150,
width: 150,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
image: const DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
"https://images.unsplash.com/photo-1585828922344-85c9daa264b0?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=640&q=80"),
)),
),
),
),
Positioned(
top: 15,
left: 180,
child: Container(
height: 150,
width: 180,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Mashroom Pizza",
style: TextStyle(
color: Color(0xff5e35b1),
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
Text(
"European Pizza",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Divider(
color: Color(0xff5e35b1),
),
],
),
),
),
Positioned(
top: 120,
left: 180,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Rating",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Text("4.5"),
],
),
),
),
Positioned(
top: 120,
left: 350,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Price",
style: TextStyle(
color: Colors.redAccent,
fontSize: 20,
),
),
Text("\$15.99"),
],
),
),
),
],
),
),
),
],
),
);
}
}
And here is my home screen code.
import 'package:flutter/material.dart';
import 'package:zar/widgets/top_card.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Home"),
),
body: Container(
child: Column(
children: const [
TopCard(),
],
),
),
);
}
}

How can I have an animated SliverAppBar like this?

I want these animation between to be smooth, I tried using AnimatedSize, AnimatedOpacity and AnimatedPositioned but there were few errors. And I don't know how to use these with SliverAppBar. In other examples I saw people using LayoutBuilder but they didn't share the full code so I couldn't test it. I will share my code snippet but it has a really odd transition between the two states.
I want CircleAvatar to become smaller and change position
I want Icon(Icons.arrow_back) and Text('Previous Page') to disappear.
I also want my name and job to disappear.
I want that three Containers to become smaller and change position.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dialog Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
elevation: 0,
pinned: true,
expandedHeight: 190,
collapsedHeight: kToolbarHeight + 8,
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.none,
centerTitle: true,
titlePadding: EdgeInsetsDirectional.only(
start: 20.0,
end: 20.0,
top: 12.0,
bottom: 12.0,
),
title: SafeArea(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CircleAvatar(
radius: 16,
),
Row(
children: [
Container(
decoration: BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
padding: EdgeInsets.all(8.0),
child: Icon(Icons.person),
),
SizedBox(
width: 8,
),
Container(
decoration: BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
padding: EdgeInsets.all(8.0),
child: Icon(Icons.menu),
),
SizedBox(
width: 8,
),
Container(
decoration: BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
padding: EdgeInsets.all(8.0),
child: Icon(Icons.message),
),
],
),
],
),
],
),
),
background: SafeArea(
child: Column(
children: [
Container(
alignment: Alignment.topLeft,
child: Row(
children: [
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
),
Text(
'PREVIOUS PAGE',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 20,
top: 12,
bottom: 24,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(
radius: 20,
),
SizedBox(
width: 12,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Sertan Hakkı İmamoğlu',
style: TextStyle(
fontSize: 18,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
'Student',
style: TextStyle(
fontSize: 14,
color: Colors.grey,
),
),
SizedBox(
height: 12,
),
Row(
children: [
Container(
decoration: BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
padding: EdgeInsets.symmetric(
horizontal: 34,
vertical: 12,
),
child: Icon(Icons.menu),
),
SizedBox(
width: 4,
),
Container(
decoration: BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
padding: EdgeInsets.symmetric(
horizontal: 34,
vertical: 12,
),
child: Icon(Icons.person),
),
SizedBox(
width: 4,
),
Container(
decoration: BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
padding: EdgeInsets.symmetric(
horizontal: 34,
vertical: 12,
),
child: Icon(Icons.message),
),
],
)
],
)
],
),
),
],
),
),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
color: index.isOdd ? Colors.white : Colors.black12,
height: 100.0,
child: Center(
child: Text('$index', textScaleFactor: 5),
),
);
},
childCount: 20,
),
),
],
),
),
);
}
}
Here's my take on your issue, as suggested by pskink I've used a SliverPersistentHeader and tried to make it responsive so when the size is reducing it has a bit of an animation.
Sample Code
class CustomPageHeader extends SliverPersistentHeaderDelegate {
CustomPageHeader({
required double collapsedHeight,
required double expandedHeight,
}) : minExtent = collapsedHeight, maxExtent = expandedHeight;
#override
final double minExtent;
#override
final double maxExtent;
Widget _buildBtn(IconData icon, double scale) {
double horizontal = 34.0 * scale;
horizontal = horizontal < 8 ? 8.0 : horizontal;
double vertical = 12.0 * scale;
vertical = vertical < 8 ? 8.0 : vertical;
return Container(
decoration: const BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
padding: EdgeInsets.symmetric(horizontal: horizontal, vertical: vertical),
child: Icon(icon),
);
}
#override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
final theme = Theme.of(context);
final backgroundColor =
theme.appBarTheme.backgroundColor ?? theme.colorScheme.primary;
final scale = 1 - shrinkOffset / maxExtent;
final isReduced = shrinkOffset >= maxExtent * 0.12;
final wrappedBtns = Wrap(
spacing: 8,
children: [
_buildBtn(Icons.menu, scale),
_buildBtn(Icons.person, scale),
_buildBtn(Icons.message, scale),
],
);
double avatarRadius = 20.0 * scale;
avatarRadius = avatarRadius > 16 ? avatarRadius : 16.0;
return Container(
padding: const EdgeInsets.only(
left: 20,
top: 12,
bottom: 12,
),
color: backgroundColor,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CircleAvatar(radius: avatarRadius),
!isReduced
? const SizedBox(width: 12)
: Expanded(child: Container()),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!isReduced)
Text(
'Sertan Hakkı İmamoğlu',
style: TextStyle(
fontSize: 18 * scale,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
if (!isReduced)
Text(
'Student',
style: TextStyle(
fontSize: 14 * scale,
color: Colors.grey,
),
),
],
),
if (isReduced) wrappedBtns,
],
),
Flexible(
child: Container(
constraints: const BoxConstraints(maxHeight: 12),
),
),
if (!isReduced) wrappedBtns,
],
),
);
}
#override
bool shouldRebuild(_) => true;
}
Use it in your sliver list like this:
SliverPersistentHeader(
pinned: true,
delegate: CustomPageHeader(
collapsedHeight: kToolbarHeight + 8,
expandedHeight: 190,
),
),
Try the full test code on DartPad
The code is perfectible but should help you enough so you can improve it and continue by yourself.

How to push down the listview without making the draggablescrollablesheet unscrollable?

I am running into issues pushing down the listview out of view of the draggablescrollablesheet (sheet) while still being able to scroll the sheet. So in simpler words I do not want the blue container to show up when the sheet is at the bottom.
I have tried to edit the height of the listview container and that makes it go offscreen therefore unscrollable.
I have also tried wrapping the sheet in a singlechildscrollview with no luck. I am trying to avoid using a button at all possible costs!
import 'package:flutter/material.dart';
import 'package:photosgroup2/chat/message_model.dart';
import 'package:photosgroup2/chat/user_model.dart';
class FeedTest extends StatefulWidget {
FeedTest({Key key}) : super(key: key);
#override
_FeedTest createState() => _FeedTest();
}
class _FeedTest extends State<FeedTest> {
_buildMessage(
Message message,
User user,
) {
//Reply reply){
String time= message.time;
return Container(
// color: Colors.yellow,
child: Padding(
padding: EdgeInsets.only(left: 0), //5
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(left: 5 ,top: 3.5), //10
child: new CircleAvatar(
radius: (17.5),
backgroundImage: AssetImage(
user.profilePic,
),
),
),
SizedBox(
width: 5,
),
Container(
//width: MediaQuery.of(context).size.width,
// width: 300,
child: Material(
color:Color(0x00000000) , //TRANSPARENT
//color: const Color(0xf2ffffff),
///Color(0xe6ffffff) // ! REVISIT Change color of boxes???
/*borderRadius: BorderRadius.only(
topRight: Radius.circular(16.0),
bottomRight: Radius.circular(16.0),
bottomLeft: Radius.circular(16.0),
),*/
child: Padding(
padding: EdgeInsets.only(
left: 10.0), //Revisit
child: Column(
//mainAxisSize: MainAxisSize.min,
mainAxisSize: MainAxisSize.min,
//crossAxis
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 5,
),
Text(
user.name,
style: TextStyle(
fontFamily: 'Lato-Bold',
fontSize: 13 ,
color: const Color(0xd9343f4b),
),
textAlign: TextAlign.left,
),
SizedBox(width: 8),
Padding(
padding: const EdgeInsets.only(left:8.0),
child: Text(
'$time hours ago',
style: TextStyle(
fontFamily: 'Lato',
fontSize: 12 ,
color: const Color(0xff5a6978),
),
textAlign: TextAlign.left,
),
),
SizedBox(
height: 5,
),
//SizedBox(height: 10,),//if(message.imageUrl!='') {
//hasReplies(message, user, reply)
//},
//}
],
),
),
),
),
],
),
SizedBox(height:5),
Container(
//color:Colors.blue,
//: EdgeInsets.only(right:10
//right: 10 * SizeConfig.widthRatio,
//),
child: Container(
//color: Colors.green,
margin: EdgeInsets.only(left:5,right:15),
child: Text(
message.text,
style: TextStyle(
fontFamily: 'Lato',
fontSize: 13 ,
color: const Color(0xff5a6978),
height: 1.5384615384615385
),
textAlign: TextAlign.left,
),
),
),
SizedBox(//color:Colors.amber,
height:15),
Transform.translate(
offset: Offset(-6,0),
child: Container(
width: 350.0,
height: 0.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(1.0),
color: const Color(0x40343f4b),
),
),
),
SizedBox(//color:Colors.amber,
height:5),
],
),
),
);
}
#override
Widget build(BuildContext context) {
// visibility of reply button in top right corner
return Scaffold(
backgroundColor: const Color(0xfffafafa),
body: SafeArea(
bottom: false,
top: false,
child: //Column(
//mainAxisAlignment: MainAxisAlignment.spaceAround,
//children: <Widget>[
Stack(
children: <Widget>[
DraggableScrollableSheet(
initialChildSize: 0.068,
minChildSize: 0.068,
maxChildSize: 0.71,
builder: (context, scrollController) {
return Container(
//padding: EdgeInsets.symmetric(horizontal: 20),
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32),
topRight: Radius.circular(32),
),
child: Container(
width: 375, //screen width
height: 812 * 0.71, //screen height *
color: Color(0xffdfdfdf),
),
),
),
Stack(
children: [
Padding(
padding: const EdgeInsets.only(left: 10, top: 20.0),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(27.5),
topRight: Radius.circular(27.5),
),
child: Container(
//margin: EdgeInsets.only(),
width:340,
//height: 515,
color: Colors.yellow,
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(27.5),
topRight: Radius.circular(27.5),),
child: Container(
// padding: EdgeInsets.only(top:40),
color: Colors.blue,
child: ListView.builder(
//reverse: true,
controller: scrollController,
itemCount: comments.length,
itemBuilder: (BuildContext context, int index) {
final User messenger = comments[index].sender;
final Message message = comments[index];
//final Reply reply = replies[index];
return Column(children: <Widget>[
_buildMessage(
message,
messenger,
), //reply),
SizedBox(
height: 8,
) // !COME BACK TO SPACE BETWEEN
]);
},
),
),
),
),),
),
],
),
Stack(
children: <Widget>[
//67
Padding(
padding: EdgeInsets.only(left: 141, top: 6),
child: SizedBox(
width: 93.0,
height: 29.0,
child: Stack(
children: <Widget>[
SizedBox(
width: 93.0,
height: 29.0,
child: Stack(
children: <Widget>[
// Adobe XD layer: 'Rectangle' (shape)
Container(
width: 93,
height: 29.0,
child: Padding(
padding: EdgeInsets.only(
left: 1, top: 6),
child: Text(
'Place Holder',
style: TextStyle(
fontFamily: 'Lato',
fontSize: 12,
color: const Color(0xffffffff),
),
textAlign: TextAlign.center,
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(27.5),
color: const Color(0xf2343f4b),
),
),
],
),
),
],
),
),
),
],
),
],
),
);
},
),
],
),
// ],
//),
),
);
}
}

Create curved card with shadow

I really need you because I don't have even start idea how to implement these, and also I am not sure how it is called.
Actually, I want to implement something similar like on image (this little circle in each of cards - that is like chain between two cards).
With help of key I have made image from up with this code:
class InfoPage extends StatefulWidget {
InfoPage();
#override
_InfoPageState createState() => _InfoPageState();
}
class _InfoPageState extends State<InfoPage> {
InfoItemModel infoData = dataSourceInfoUser;
double basicSize = 70;
#override
initState() {
super.initState();
}
#override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text('Example'),
),
body: Container(
color: Colors.white,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
width: double.infinity,
height: 150,
child: AppCardField(
child: Text('Something'),
),
),
_buildCardWithCircle(
bgCircleX: 0.78,
bgCirceY: -2.0,
innerContainerX: 0.756,
innerContainerY: -1.78,
colorInner: Colors.orange
),
],
),
),
),
);
_buildCardWithCircle({double bgCircleX, double bgCirceY, double innerContainerX, double innerContainerY, Color colorInner}) => Container(
width: double.infinity,
height: 150,
child: Stack(
children: <Widget>[
Container(
width: double.infinity,
height: 150,
child: AppCardField(
child: Text('Something'),
),
),
Align(
alignment: Alignment(bgCircleX, bgCirceY),
child: Container(
height: basicSize,
width: basicSize,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(50.0),
),
),
),
Align(
alignment: Alignment(innerContainerX, innerContainerY),
child: Container(
height: basicSize - 10,
width: basicSize - 10,
decoration: BoxDecoration(
color: colorInner,
borderRadius: BorderRadius.circular(50.0),
),
child: Icon(Icons.vertical_align_center),
),
),
],
),
);
}
class AppCardField extends StatelessWidget {
final Widget child;
final double height;
final double paddingVertical, paddingHorizontal;
final double paddingVerticalChild, paddingHorizontalChild;
AppCardField({
this.child,
this.height,
this.paddingVertical = 8,
this.paddingHorizontal = 16,
this.paddingVerticalChild = 8,
this.paddingHorizontalChild = 16,
Key key})
: super(key: key);
#override
Widget build(BuildContext context) => Padding(
padding: EdgeInsets.symmetric(
vertical: paddingVertical, horizontal: paddingHorizontal),
child: Container(
height: height,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.all(Radius.circular(8)),
boxShadow: [
BoxShadow(
color: Colors.red,
blurRadius: 15.0,
offset: Offset(0.0, 5.0),
),
],
),
child: Padding(
padding: EdgeInsets.symmetric(
vertical: paddingVerticalChild,
horizontal: paddingHorizontalChild),
child: child,
),
));
}
But here, I have problem with shadow of the card and strongly white background of circle, OFC I need this shadow to be also in this white space, question is how to solve this?
Something like this
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Some Stuff"),
),
body: Column(
children: <Widget>[
Container(
width: double.infinity,
height: 150.0,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.red,
blurRadius: 20.0
)
]
),
child: Card(
elevation: 20.0,
color: Colors.blueGrey,
child: Text('Something'),
),
),
SizedBox(height: 10.0,),
Container(
width: double.infinity,
height: 150.0,
child: Stack(
children: <Widget>[
Container(
width: double.infinity,
height: 150.0,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.red,
blurRadius: 20.0
)
]
),
child: Card(
elevation: 20.0,
color: Colors.blueGrey,
child: Text('Something'),
),
),
Align(
alignment: Alignment(0.9,-1.5),
child: Container(
height: 50.0,
width: 50.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25.0),
),
),
),
Align(
alignment: Alignment(0.88,-1.35),
child: Container(
height: 40.0,
width: 40.0,
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(25.0),
),
),
),
Align(
alignment: Alignment(0.85, -1.2),
child: Icon(Icons.access_alarms, color: Colors.white,)
),
],
),
),
],
),
),
);
then you just reaped the card for the other once with different alignment values.

Trouble Building a Scroll-able Page with a bottom-navigation-Bar

When I am adding a bottomNavigationBar to my Page, the body of my Page will disappear. I believe the porblem to be sourced with my use of SingleChildScrollView from other posts that I have read
It does not appear to matter where I call in the bottom navigation Bar the page stops working
-homeScreen.dart
import 'package:flutter/material.dart';
import 'package:second_try/Widgets/headerHome.dart';
import 'package:second_try/Widgets/menuHome.dart';
import 'package:second_try/Widgets/businessesList.dart';
class homeScreen extends StatefulWidget {
homeScreen({Key key, this.title}) : super(key: key);
final String title;
#override
_homeScreen createState() => _homeScreen();
}
class _homeScreen extends State<homeScreen> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(body: bodyHomePage()),
);
}
}
class bodyHomePage extends StatelessWidget {
const bodyHomePage({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SingleChildScrollView(
child: Column(children: <Widget>[
headerHome(),
homeMenu(),
businessesList(),
businessesList(),
]),
),
// bottomNavigationBar: bottomNavigation(),
),
);
}
}
-------------------------------------------------------------------------------------
headerHome
import 'package:flutter/material.dart';
class headerHome extends StatelessWidget {
const headerHome({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: Container(
height: 140,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Container(
height: 140,
color: Colors.white,
),
Container(
height: 120,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.deepPurple,
Colors.deepPurpleAccent,
],
),
boxShadow: [
BoxShadow(
color: Colors.black,
blurRadius: 10,
),
]),
),
Positioned(
top: 98,
child: Container(
width: 340,
height: 40,
decoration: BoxDecoration(
boxShadow: [
new BoxShadow(
color: Colors.blueGrey[900],
offset: new Offset(0.0, 8.0),
blurRadius: 20.0,
)
],
borderRadius: BorderRadius.all(Radius.circular(20)),
color: Colors.white,
),
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Padding(
padding:
const EdgeInsets.only(top: 8, left: 10),
child: TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "What are you looking for?",
hintStyle:
TextStyle(color: Colors.grey[700]),
),
),
),
),
Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: Alignment.centerRight,
child: Icon(Icons.search,
color: Colors.deepPurple)),
),
),
])),
),
Container(
height: 100,
padding: EdgeInsets.only(top: 25),
child: Row(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 30),
height: 35,
/* child: Image(
image: AssetImage(
'lib/assets/white-boardwalk-icon.png',
),
),*/
),
],
),
),
Container(
height: 100,
padding: EdgeInsets.only(top: 25),
child: Row(
children: <Widget>[
Expanded(
child: Center(
child: Container(
child: Text(
'Boardwalk',
style:
TextStyle(fontSize: 30, color: Colors.white),
),
),
),
),
],
),
),
],
),
],
),
),
);
}
}
-----------------------------------------------------------------------------------------------
businessList.dart
import 'package:flutter/material.dart';
class businessesList extends StatelessWidget {
const businessesList({Key key}) : super(key: key);
Padding businessCard(String category, IconData categoryIcon) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Container(
margin: EdgeInsets.only(left: 21),
width: 200,
child: InkWell(
child: Column(
children: <Widget>[
Center(
child: Container(
height: 140,
width: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(14)),
gradient: LinearGradient(
colors: [Colors.deepPurple, Colors.deepPurpleAccent],
),
),
child: Icon(
categoryIcon,
size: 40.0,
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 12),
child: Align(
alignment: Alignment.topLeft,
child: Text(
category,
style: TextStyle(
fontSize: 22,
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 6),
child: Row(
children: <Widget>[
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Padding(
padding: const EdgeInsets.only(left:6.0),
child: Text(
'(356)',
style: TextStyle(
fontSize: 14,
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 6),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'Sed ut perspiciatis unde omnis iste natus error sit',
style: TextStyle(
fontSize: 16,
),
),
),
),
],
),
),
));
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 6, bottom: 12.0),
child: Container(
height: 40,
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 35),
alignment: Alignment.centerLeft,
child: Text(
'List Header',
style: TextStyle(fontSize: 24),
)),
Expanded(
child: SizedBox(),
),
Container(
margin: EdgeInsets.only(right: 35),
alignment: Alignment.centerRight,
child: Text(
'View All',
style: TextStyle(fontSize: 16),
))
],
),
),
),
Container(
height: 260,
width: 400,
child:
ListView(scrollDirection: Axis.horizontal, children: <Widget>[
businessCard('Home', Icons.home),
businessCard('Eat', Icons.restaurant_menu),
businessCard('Shop', Icons.store),
businessCard('Travel', Icons.airplanemode_active),
businessCard('Play', Icons.local_activity),
businessCard('Service', Icons.business),
]),
),
],
),
);
}
--------------------------------------------------------------------------------
bottomNavigation.dart
import 'package:flutter/material.dart';
class bottomNavigation extends StatelessWidget {
const bottomNavigation ({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: 1,
items: [
BottomNavigationBarItem(icon: Icon(Icons.arrow_drop_up,), title: Text("GLO",
style: TextStyle(color: Colors.black),),),
BottomNavigationBarItem(icon: Icon(Icons.arrow_drop_up), title:
Text("MTN"),),
BottomNavigationBarItem(icon: Icon(Icons.arrow_drop_up), title:
Text("Airtel"),),
BottomNavigationBarItem(icon: Icon(Icons.arrow_drop_up), title:
Text("Airtel"),),
],
),
),
);
}
}
I am expecting both the Pages Screen and the navigation bar to be view-able but the two are not working together at the moment
I am not experiencing any error messages
_homeScreen, bodyHomePage and bottomNavigation build methods return MaterialApp - you should need only one MaterialApp, in _homeScreen, the rest should be widgets. – Melquiades 7 mins ago
Thanks for the fast help. I though I needed to call MaterialApp if I was building components outside of that original page. Thanks for the quick fix! just starting using flutter a few days ago