How to overlap two circles? - flutter

Can someone help me get this layout with the first circle over the second?
image
I have this function:
Widget overlapped() {
final overlap = 25;
final items = [
Container(
padding: EdgeInsets.only(right: 2),
decoration: new BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
child: CircleAvatar(
radius: 22,
backgroundImage: AssetImage('assets/example_logo.png'),
backgroundColor: Colors.black,
),
),
CircleAvatar(
radius: 22,
backgroundColor: Colors.white,
child: ClipOval(
child: Image.network(
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/1200px-Google_%22G%22_Logo.svg.png",
errorBuilder: (context, exception, stackTrace) {
return Container(color: Colors.white);
},
height: 35,
))),
CircleAvatar(
child: Text('+2', style: TextStyle(color: Colors.white)),
backgroundColor: Theme.of(context).canvasColor),
];
List<Widget> stackLayers = List<Widget>.generate(items.length, (index) {
return Container(
padding: EdgeInsets.fromLTRB(index.toDouble() * overlap, 0, 0, 0),
child: items[index],
);
});
return Stack(children: stackLayers);
}
This function whenever I add an item to the array, it adds a widget on the right. But I want the first to be above the second, the second of the third, etc ...

you could use the Stack widget :
Stack(
children:<Widget>:[
Positioned(
right: 130.0,
child:Container(
shape: BoxShape.circle,
)
),
Positioned(
left: 130.0,
child:Container(
shape: BoxShape.circle,
)
),
]
)

Use Stack and Positioned together.
import 'package:flutter/material.dart';
class OverLap extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Overlap'),
),
body: Container(
padding: const EdgeInsets.all(8.0),
width: 500.0,
child: Stack(
children: <Widget>[
//Change according to your icon
Icon(
Icons.flaky,
size: 50.0,
color: Colors.red,
),
Positioned(
left: 20.0,
//Change according to your icon
child: Icon(
Icons.flaky,
size: 50.0,
color: Colors.blue,
),
),
],
),
),
);
}
}

Related

button shadow when clicked is covered by other widget

Button's shadow is happened when click the button.
But, the shadow is covered by other widget.
How can I resolve this?
#override
Widget build(BuildContext context) {
int total = 0;
for (int i = 1; i <= count; i++) {
total += i;
}
return Stack(
clipBehavior: Clip.none,
children: [
Container(
width: 343.43,
height: 150.62,
decoration: RadiusAndShadow().getDecoration(),
child: Column(
children: <Widget>[
Header(text: name),
EcRow(t1: '칼로리', t2: '1회당 ${calorie}kcal'),
EcRow(t1: '카드개수', t2: '$count 개'),
EcRow(t1: '반복횟수', t2: '$total회'),
],
),
),
Positioned(
width: 343.43,
height: 150.62,
top: 17,
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
),
child: IconButton(
padding: const EdgeInsets.all(0),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ExEdit();
}));
},
icon: const Icon(
Icons.edit_outlined,
color: Colors.white,
size: 30,
),
),
),
),
),
],
);
}
I used Stack widget.
In Stack, there are Container and Positioned.
In Container, there are Header and Text.
In Positioned, there is an IconButton.
I didn't understand exactly what happens since you did not provide any code, but I think when you click on the IconButton a splash effect happens and not exactly a shadow so inside the IconButton add:
splashRadius: 20,
you can also disable this effect:
return Theme(
data: ThemeData.light().copyWith(
textTheme: GoogleFonts.poppinsTextTheme(),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: const WelcomeScreen(),
);
Wrap your IconButton with widget Material
in Material
color: Colors.transparent,
in IconButton
splashRadius: 20,

Flutter SliverList freezes while its loading images

I have a flutter app. One of my screens is loading lots of images from assets. Sometimes my app is freezing while the images are loading.
Here is my solution: I will put a loading animation, this animation needs to end up after the images are finished rendering but how do I understand all the images are finished rendering?
If you have any other solutions you can share with me :)
here is the Widget tree that loads images, in case if you need to know.
final posts = [
Post(
ownerName: "McQueen95",
avatarPath: "images/mcqueen.jpg",
imagePaths: ['images/mcqueen.jpg'],
),
Post(
ownerName: "BugsBunny",
imagePaths: ['images/Bugs_Bunny.png'],
),
Post(
ownerName: "Venom",
imagePaths: ['images/venom.jpg'],
),
Post(
ownerName: "Po",
imagePaths: ["images/kungfu_panda.jpg"],
avatarPath: "images/po.jpg",
),
Post(
ownerName: "Po",
imagePaths: ["images/kai.jpg", "images/oogway.jpg", "images/crane.png"],
avatarPath: "images/po.jpg",
),
];
#override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
SliverAppBar(
title: Text("Cossy", style: TextStyle(color: Colors.purple)),
// elevation: 0,
pinned: true,
// expandedHeight: 150.0,
backgroundColor: backgroundColor,
systemOverlayStyle: SystemUiOverlayStyle(
systemNavigationBarColor: backgroundColor,
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Padding(
child: posts[index],
padding: EdgeInsets.only(
bottom: (index == posts.length - 1) ? 82 : 12,
),
),
childCount: posts.length,
),
)
],
);
}
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_image_slider/carousel.dart';
class Post extends StatelessWidget {
Post({
Key? key,
this.avatarPath,
required this.ownerName,
required this.imagePaths,
}) : super(key: key);
final String? avatarPath;
final String ownerName;
final List<String> imagePaths;
#override
Widget build(BuildContext context) {
if (imagePaths.length == 0) return Text("no image?");
return Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Color(0xFFF2F2F2),
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 6.0,
),
],
// color: Color(0xFFF2F2F2),
color: Colors.deepOrange,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
children: [
CircleAvatar(
child: avatarPath == null ? Icon(Icons.person) : null,
backgroundImage:
avatarPath == null ? null : AssetImage(avatarPath ?? ""),
),
SizedBox(width: 10),
Text(ownerName),
Expanded(
child: SizedBox(height: 30),
),
Icon(Icons.settings),
],
),
),
Carousel(
indicatorBarColor: Colors.transparent,
autoScrollDuration: Duration(seconds: 2),
animationPageDuration: Duration(milliseconds: 500),
activateIndicatorColor: Colors.grey.shade200,
animationPageCurve: Curves.bounceInOut,
indicatorBarHeight: 30,
indicatorHeight: 10,
indicatorWidth: 20,
unActivatedIndicatorColor: Colors.grey.shade700,
stopAtEnd: true,
autoScroll: false,
// widgets
items: imagePaths
.map(
(imagePath) => Container(
decoration: BoxDecoration(color: Colors.black),
child: ConstrainedBox(
constraints: new BoxConstraints(
minHeight: 100,
minWidth: 100,
// maxHeight: 500,
maxHeight: MediaQuery.of(context).size.height * 3 / 2,
maxWidth: MediaQuery.of(context).size.width,
),
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.center,
child: Image(
image: AssetImage("$imagePath"),
),
),
),
),
)
.toList(),
),
Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
top: 4,
),
child: Row(
children: [
TextButton(
onPressed: () {
print(123);
},
child: Icon(
Icons.star_border_outlined,
size: 30,
// color: Colors.grey,
),
),
Expanded(
child: SizedBox(
height: 30,
),
),
Icon(
Icons.send_outlined,
size: 30,
// color: Colors.grey,
),
],
),
),
],
),
);
}
}
I solved the bug by giving certain height and width values to the Widget that contains images. Using ConstrainedBox and FittedBox means it will load images first and then measure all items' height and widths and then give height value to ListView. So, that's why the app freezes, measuring ListView's size takes a lot of time.
I changed this:
Container(
decoration: BoxDecoration(color: Colors.black),
child: ConstrainedBox(
constraints: new BoxConstraints(
minHeight: 100,
minWidth: 100,
maxHeight: MediaQuery.of(context).size.height * 3 / 2,
maxWidth: MediaQuery.of(context).size.width,
),
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.center,
child: Image(
image: AssetImage("$imagePath"),
),
),
),
),
To this:
AspectRatio(
aspectRatio: 1 / 1,
child: Container(
decoration: BoxDecoration(color: Colors.black),
width: MediaQuery.of(context).size.width,
alignment: Alignment.center,
child: ClipRRect(
// borderRadius: BorderRadius.circular(10),
child: Image(
image: AssetImage("${imagePaths[0]}"),
),
),
),
),

Designing a Flutter button with image and text

If I just throw together an image and some text in a rounded-corner rectangle, the user will not know that they can "click here". But I don't have to bake my own solution. InkWell covers this scenario, complete with a nice shadow.
I am positioning
a custom clickable icon using the
InkWell
class, itself requiring to be inside an
Ink
instance.
import 'package:flutter/material.dart';
const boat_url = ('https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/'
'Segelboot_Bodensee_Mainau_%28Foto_Hilarmont%29.JPG/'
'182px-Segelboot_Bodensee_Mainau_%28Foto_Hilarmont%29.JPG');
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Image',
home: Scaffold(
backgroundColor: Colors.grey,
body: MyImage(),
)));
}
class MyImage extends StatelessWidget {
MyImage({Key key,});
#override
Widget build(BuildContext context) {
Size sz = MediaQuery.of(context).size * 0.4;
double border = 4;
return Stack(children: [
Positioned(
top: 100,
left: 100,
width: sz.width,
height: sz.height,
child: Material(
child: Ink(
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
new BoxShadow(
color: Colors.red,
blurRadius: 10.0,
offset: new Offset(30.0, 20.0),
),
],
border: Border.all(
color: Colors.blue,
width: border,
),
borderRadius: BorderRadius.circular(40),
),
child: InkWell(
onTap: (){/*..*/},
child: Column(
children: [
Container(
height: 4 * (sz.height - 2 * border) / 5,
alignment: Alignment.center,
child: Image.network(boat_url),
),
Container(
height: (sz.height - 2 * border) / 5,
child: FittedBox(
clipBehavior: Clip.antiAlias,
alignment: Alignment.centerLeft,
fit: BoxFit.fitHeight,
child: Text('A long descriptive sentence')),
)
],
)),
),
)),
]);
}
}
1- I'm not actually using Colors.white, and the Scaffold itself has
backgroundColor: Colors.grey. Where is the white background coming from?
2- When we talk of a "shadow", I'm expecting the shadow to be behind
the ink/inkwell object. Why does the shadow appear in front?
Related: 1
That white color is from the Material widget, to remove that you can use type param.
Material(
type: MaterialType.transparency,
child: Container(),
);
Here is code to achieve the custom button
Video link
Scaffold(
backgroundColor: Colors.blueGrey,
body: SafeArea(
child: Container(
decoration: BoxDecoration(
color: Colors.green.shade200,
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(5),
boxShadow: [
BoxShadow(
blurRadius: 5,
spreadRadius: 2,
color: Colors.black26,
)
]),
margin: const EdgeInsets.all(20),
child: Material(
type: MaterialType.transparency,
child: InkWell(
onTap: () {},
splashColor: Colors.black26,
child: IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Image.asset(
'assets/images/marked_tyre_base.png',
fit: BoxFit.cover,
width: 80,
height: 80,
),
const SizedBox(
height: 10,
),
Text(
'Tyre 1',
style: TextStyle(color: Colors.white),
)
]),
),
),
),
),
),
),
);
Screenshot:
Create a class, ImageTextButton:
class ImageTextButton extends StatelessWidget {
final VoidCallback onPressed;
final ImageProvider image;
final double imageHeight;
final double radius;
final Widget text;
ImageTextButton({
#required this.onPressed,
#required this.image,
this.imageHeight = 200,
this.radius = 28,
#required this.text,
});
#override
Widget build(BuildContext context) {
return Card(
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(radius)),
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: onPressed,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Ink.image(
image: image,
height: imageHeight,
fit: BoxFit.cover,
),
SizedBox(height: 6),
text,
SizedBox(height: 6),
],
),
),
);
}
}
Usage:
ImageTextButton(
onPressed: () {},
image: AssetImage('chocolate_image'),
text: Text('Chocolate'),
)

How to clip one container over another in flutter?

I want to build a reusable card widget, it will have an image and text with some custom design layout. I tried everything I could, but wasn't able to achieve the desired result. Any help would be much appreciated.
This is what I want to do
I'm stuck here
This is my code
class ReusabelCard extends StatelessWidget {
ReusabelCard(
{this.cardChild, #required this.assetImagePath, #required this.cardText});
final Widget cardChild;
final String assetImagePath;
final String cardText;
#override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.35,
width: MediaQuery.of(context).size.width * 0.5,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(MediaQuery.of(context).size.width * 0.5 * 0.28),
),
child: Stack(
children: [
LayoutBuilder(
builder: (context, contraint) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Icon(
Icons.trip_origin,
size: contraint.biggest.width,
color: Colors.grey[300],
),
Container(
height: MediaQuery.of(context).size.height*0.05,
width: MediaQuery.of(context).size.width,
color: Colors.green,
),
],
);
},
),
],
)
);
}
}
Use ClipRRect to do it:
ClipRRect(
borderRadius: BorderRadius.circular(50.0), //clipping the whole widget
child: Container(
height: MediaQuery.of(context).size.height * 0.4, //I adjusted here for responsiveness problems on my device
width: MediaQuery.of(context).size.width * 0.5,
color: Colors.white,
child: LayoutBuilder(
builder: (context, constraint) {
return Stack(
children: [
Center(
child: Icon(
Icons.trip_origin,
size: constraint.biggest.width,
color: Colors.grey[300],
),
),
Positioned(
right: 0,
left: 0,
top: 20.0,
child: Icon(
Icons.sports_volleyball_rounded, //just to represent the ball
size: constraint.biggest.width * 0.5,
),
),
Positioned(
bottom: 0.0,
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.1,
width: constraint.biggest.width,
color: Colors.yellow[700],
child: Text(
'Sports',
style: Theme.of(context)
.textTheme
.headline3
.copyWith(color: Colors.white),
),
),
),
],
);
},
),
),
);

How to Give BorderRadius to SliverList

I am using SliverAppBar and SliverListView in my project.
I need BorderRadius to my SliverList that is coming bottom of my SliverAppBar.
Here is screenshot what I need :
And here is my code:
Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
backgroundColor: Colors.transparent,
brightness: Brightness.dark,
actions: <Widget>[
IconButton(icon: Icon(Icons.favorite), onPressed: () {}),
IconButton(icon: Icon(Icons.share), onPressed: () {})
],
floating: false,
pinned: false,
//title: Text("Flexible space title"),
expandedHeight: getHeight(context) - MediaQuery.of(context).padding.top,
flexibleSpace: Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage("assets/images/Rectangle-image.png")
)
),
),
bottom: _bottomWidget(context),
),
SliverList(
delegate: SliverChildListDelegate(listview),
),
],
),
)
So, with this code the UI is coming like this...
can suggest any other approach that i can take to achieve this kind of design...
I achieved this design using SliverToBoxAdapter my code like this.
final sliver = CustomScrollView(
slivers: <Widget>[
SliverAppBar(),
SliverToBoxAdapter(
child: Container(
color: Color(0xff5c63f1),
height: 20,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
height: 20,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(20.0),
topRight: const Radius.circular(20.0),
),
),
),
],
),
),
),
SliverList(),
],
);
I used 2 containers inside SliverToBoxAdapter.
SliverToBoxAdapter is between the Sliver Appbar and the Sliver List.
first I create a blue (should be Appbar color) container for the corner edge.
then I create the same height white container with border-radius inside the blue container for list view.
Preview on dartpad
Solution
At the time of writing, there is no widget that would support this functionality. The way to do it is with Stack widget and with your own SliveWidget
Before:
Here is your default code:
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: 'Flexible space title',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
backgroundColor: Colors.transparent,
brightness: Brightness.dark,
actions: <Widget>[IconButton(icon: Icon(Icons.favorite), onPressed: () {}), IconButton(icon: Icon(Icons.share), onPressed: () {})],
floating: false,
pinned: false,
expandedHeight: 250 - MediaQuery.of(context).padding.top,
flexibleSpace: Container(
height: 550,
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
'https://images.unsplash.com/photo-1561752888-21eb3b67eb4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=967&q=80'))),
),
//bottom: _bottomWidget(context),
),
SliverList(
delegate: SliverChildListDelegate(_listview(50)),
),
],
),
),
);
}
}
List _listview(int count) {
List<Widget> listItems = List();
listItems.add(Container(
color: Colors.black,
height: 50,
child: TabBar(
tabs: [FlutterLogo(), FlutterLogo()],
),
));
for (int i = 0; i < count; i++) {
listItems.add(new Padding(padding: new EdgeInsets.all(20.0), child: new Text('Item ${i.toString()}', style: new TextStyle(fontSize: 25.0))));
}
return listItems;
}
After
And here is your code done with Stack and SliveWidget widgets:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.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: 'Flexible space title',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
body: Stack(
children: [
Container(
height: 550,
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
'https://images.unsplash.com/photo-1561752888-21eb3b67eb4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=967&q=80'))),
),
CustomScrollView(
anchor: 0.4,
slivers: <Widget>[
SliverWidget(
child: Container(
width: double.infinity,
height: 100,
decoration: BoxDecoration(
color: Colors.yellow, borderRadius: BorderRadius.only(topLeft: Radius.circular(30), topRight: Radius.circular(30))),
child: TabBar(
tabs: [FlutterLogo(), FlutterLogo()],
),
),
),
SliverList(
delegate: SliverChildListDelegate(_listview(50)),
),
],
),
],
),
),
);
}
}
List _listview(int count) {
List<Widget> listItems = List();
for (int i = 0; i < count; i++) {
listItems.add(
Container( //NOTE: workaround to prevent antialiasing according to: https://github.com/flutter/flutter/issues/25009
decoration: BoxDecoration(
color: Colors.white, //the color of the main container
border: Border.all(
//apply border to only that side where the line is appearing i.e. top | bottom | right | left.
width: 2.0, //depends on the width of the unintended line
color: Colors.white)),
child: Container(
padding: EdgeInsets.all(20),
color: Colors.white,
child: new Text(
'Item ${i.toString()}',
style: new TextStyle(fontSize: 25.0),
),
),
),
);
}
return listItems;
}
class SliverWidget extends SingleChildRenderObjectWidget {
SliverWidget({Widget child, Key key}) : super(child: child, key: key);
#override
RenderObject createRenderObject(BuildContext context) {
// TODO: implement createRenderObject
return RenderSliverWidget();
}
}
class RenderSliverWidget extends RenderSliverToBoxAdapter {
RenderSliverWidget({
RenderBox child,
}) : super(child: child);
#override
void performResize() {}
#override
void performLayout() {
if (child == null) {
geometry = SliverGeometry.zero;
return;
}
final SliverConstraints constraints = this.constraints;
child.layout(constraints.asBoxConstraints(/* crossAxisExtent: double.infinity */), parentUsesSize: true);
double childExtent;
switch (constraints.axis) {
case Axis.horizontal:
childExtent = child.size.width;
break;
case Axis.vertical:
childExtent = child.size.height;
break;
}
assert(childExtent != null);
final double paintedChildSize = calculatePaintOffset(constraints, from: 0.0, to: childExtent);
final double cacheExtent = calculateCacheOffset(constraints, from: 0.0, to: childExtent);
assert(paintedChildSize.isFinite);
assert(paintedChildSize >= 0.0);
geometry = SliverGeometry(
scrollExtent: childExtent,
paintExtent: 100,
paintOrigin: constraints.scrollOffset,
cacheExtent: cacheExtent,
maxPaintExtent: childExtent,
hitTestExtent: paintedChildSize,
);
setChildParentData(child, constraints, geometry);
}
}
Use Stack. It's the best and smooth way I found and used.
Preview
import 'dart:math';
import 'package:agro_prep/views/structure/constant.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class CropDetailsPage extends StatelessWidget {
const CropDetailsPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
backgroundColor: Colors.white,
actions: <Widget>[
IconButton(icon: Icon(Icons.share), onPressed: () {})
],
floating: false,
pinned: false,
//title: Text("Flexible space title"),
expandedHeight: 281.h,
flexibleSpace: Stack(
children: [
const Positioned.fill(
child: FadeInImage(
image: NetworkImage(tempImage),
placeholder: const NetworkImage(tempImage),
// imageErrorBuilder: (context, error, stackTrace) {
// return Image.asset('assets/images/background.jpg',
// fit: BoxFit.cover);
// },
fit: BoxFit.cover,
),
),
Positioned(
child: Container(
height: 33.h,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(
top: Radius.circular(40),
),
),
),
bottom: -7,
left: 0,
right: 0,
)
],
),
),
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return ListTile(
tileColor: whiteColor,
title: Text(Random().nextInt(100).toString()),
);
}, childCount: 15))
],
),
);
}
}
Worked for me!
SliverAppBar(
pinned: true,
floating: false,
centerTitle: true,
title: TextWidget(detail.title,
weight: FontWeight.bold
),
expandedHeight: MediaQuery.of(context).size.height/2.5,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
collapseMode: CollapseMode.parallax,
background: Stack(
children: [
// Carousel images
Swiper(
itemWidth: MediaQuery.of(context).size.width,
itemHeight: MediaQuery.of(context).size.height /3.5,
itemCount: 2,
pagination: SwiperPagination.dots,
loop: detail.banners.length > 1,
itemBuilder: (BuildContext context, int index) {
return Image.network(
'https://image.com?image=123.png',
fit: BoxFit.cover
);
}
),
//Border radius
Align(
alignment: Alignment.bottomCenter,
child: Container(
color: Colors.transparent,
height: 20,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
height: 10,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(10),
topRight: const Radius.circular(10),
),
),
),
],
),
),
)
],
),
),
)
So the best way to achieve your result is to use "bottom" poperty inside SliverAppBar. This will add your rounded container to bottom of appbar / start of sliverlist
bottom: PreferredSize(
preferredSize: const Size.fromHeight(24),
child: Container(
width: double.infinity,
decoration: const BoxDecoration(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12),
),
color: Colors.white,
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(2),
),
),
),
],
),
),
),
The idea is good but it looks odd in some cases.
You could give a borderRadius to your first element in your list
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(index == 0 ? 15 : 0),
topLeft: Radius.circular(index == 0 ? 15 : 0),
),
),
)
Hope this helps someone
Try This, It's a Simple Solution
import 'package:flutter/material.dart';
class SliveR extends StatelessWidget {
const SliveR({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
SizedBox(
width: double.infinity,
child: Image.network(
'https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2700&q=80',
fit: BoxFit.cover,
height: MediaQuery.of(context).size.height * 0.35,
),
),
Align(
alignment: Alignment.topCenter,
child: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30)),
),
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(30)),
child: CustomScrollView(
anchor: 0.3,
slivers: [
SliverToBoxAdapter(
child: Container(
height: 900,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(40.0),
topRight: Radius.circular(40.0),
),
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 16.0,
),
],
),
child: const Center(
child: Text(
'Hello',
style: TextStyle(color: Colors.grey),
),
),
),
)
],
),
),
),
),
],
),
);
}
}
FlexibleSpaceBar(
title: CustomText(
text: "Renaissance Concourse Hotel",
textSize: kSubtitle3FontSize,
fontWeight: kBold),
centerTitle: true,
collapseMode: CollapseMode.pin,
background: Stack(
children: [
CachedNetworkImage(
imageUrl:
"url",
width: DeviceUtils.getWidth(context),
fit: BoxFit.cover,
placeholder: (context, url) => const Center(
child: CircularProgressIndicator(),
),
errorWidget: (context, url, error) =>
const Icon(Icons.error_rounded),
),
Positioned(
bottom: 50,
right: 0,
left: 0,
child: ContainerPlus(
color: kWhiteColor,
child: const SizedBox(
height: 20,
),
radius: RadiusPlus.only(
topLeft: kBorderRadiusValue10,
topRight: kBorderRadiusValue10,
),
),
)
],
))