Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 902 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to overlap SliverList on a SliverAppBar

#1
I'm trying to overlap a `SliverList` a few pixels over the `SliverAppBar`. Similar to [this post][1]. I'd like the image in the `FlexibleSpaceBar` to go under the radius of my `SliverList`.
I'm attempting to achieve the below.

[![enter image description here][2]][2]

I can only get the radius like so. Without the ability to overlap the `SliverList` onto he `SliverAppBar`.
[![enter image description here][3]][3]


```
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
floating: false,
expandedHeight: MediaQuery.of(context).size.height * 0.50,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(pet.photos.first)
),
),
SliverList(
delegate: SliverChildListDelegate([
Container(
height: 40,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
),
),
]),
)
],
),
);
}
```

Any direction would be appreciated, thanks!

[1]:

[To see links please register here]

[2]:

[3]:
Reply

#2
You can use the following widget which uses Stack and scroll listeners to achieve something like the screenshots. It's based on

[To see links please register here]

.

**The widget:**
```dart
import 'package:flutter/material.dart';

class DetailScaffold extends StatefulWidget {
final ScrollController controller;
final ScrollPhysics physics;
final List<Widget> slivers;

final double expandedHeight;

/// Changes edge behavior to account for [SliverAppBar.pinned].
///
/// Hides the edge when the [ScrollController.offset] reaches the collapsed
/// height of the [SliverAppBar] to prevent it from overlapping the app bar.
final bool hasPinnedAppBar;

DetailScaffold({
@required this.expandedHeight,
this.controller,
this.physics,
this.slivers,
this.hasPinnedAppBar = false,
}) {
assert(expandedHeight != null);
assert(hasPinnedAppBar != null);
}

@override
_DetailScaffoldState createState() => _DetailScaffoldState();
}

class _DetailScaffoldState extends State<DetailScaffold> {
ScrollController ctrl;

@override
void initState() {
super.initState();

ctrl = widget.controller ?? ScrollController();
ctrl.addListener(() => setState(() {}));
}

@override
void dispose() {
if (widget.controller == null) {
ctrl.dispose();
}

super.dispose();
}

@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
CustomScrollView(
controller: ctrl,
physics: widget.physics,
slivers: widget.slivers,
),
_buildEdge(),
],
);
}

_buildEdge() {
var edgeHeight = 12.0;
var paddingTop = MediaQuery.of(context).padding.top;

var defaultOffset =
(paddingTop + widget.expandedHeight) - edgeHeight;

var top = defaultOffset;
var edgeSize = edgeHeight;

if (ctrl.hasClients) {
double offset = ctrl.offset;
top -= offset > 0 ? offset : 0;

if (widget.hasPinnedAppBar) {
// Hide edge to prevent overlapping the toolbar during scroll.
var breakpoint =
widget.expandedHeight - kToolbarHeight - edgeHeight;

if (offset >= breakpoint) {
edgeSize = edgeHeight - (offset - breakpoint);
if (edgeSize < 0) {
edgeSize = 0;
}

top += (edgeHeight - edgeSize);
}
}
}

return Positioned(
top: top,
left: 0,
right: 0,
child: Container(
height: edgeSize,
decoration: BoxDecoration(
color: Theme.of(context).canvasColor,
borderRadius: BorderRadius.vertical(
top: Radius.circular(12),
),
),
),
);
}
}
```

**Using it:**

```dart
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
var expandedHeight = 128.0;

return DetailScaffold(
expandedHeight: expandedHeight,
slivers: <Widget>[
SliverAppBar(
expandedHeight: expandedHeight,
flexibleSpace: FlexibleSpaceBar(
background: Container(color: Colors.purple),
),
),
SliverList(
delegate: SliverChildBuilderDelegate((_, i) {
return ListTile(title: Text('Item $i'));
}, childCount: 50),
),
],
);
}
}
```

Reply

#3
I found an easier way to achieve that:

```dart
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'How to overlap SliverList on a SliverAppBar',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Home(),
);
}
}

class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
bottom: PreferredSize(
child: Container(),
preferredSize: Size(0, 20),
),
pinned: false,
expandedHeight: MediaQuery.of(context).size.height * 0.4,
flexibleSpace: Stack(
children: [
Positioned(
child: Image(
fit: BoxFit.cover,
image: NetworkImage(
"https://images.pexels.com/photos/62389/pexels-photo-62389.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",
),
),
top: 0,
left: 0,
right: 0,
bottom: 0),
Positioned(
child: Container(
height: 30,
decoration: BoxDecoration(
color: Colors.lightBlue[100],
borderRadius: BorderRadius.vertical(
top: Radius.circular(50),
),
),
),
bottom: -1,
left: 0,
right: 0,
),
],
),
),
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index + 1 % 9)],
child: Text('List Item $index'),
);
},
),
),
],
),
);
}
}

```

You can see it in DartPad: [

[To see links please register here]

]
[1]

The important part is to use a stack in the flexibleSpace that contains the content you wanna show as a positioned widget and another position widget with the border decoration.

You also need to use the bottom section of the SliverAppBar setting the preferred size as the same as the widget with border decoration.

The DartPad does not render the widget properly (it shows a margin at the bottom, but this does not happen in the iOS/Android).


[1]:

[To see links please register here]

Reply

#4
I found an way to achieve that:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(

),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);


final String title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
AnimationController animController;
Animation<double> animation;
bool monhani = true;

int _counter = 0;
ScrollController _scrollController;

@override
void initState() {
animController = AnimationController(
duration: Duration(microseconds: 300000),
vsync: this,
);
animation = Tween<double>(begin: 150.0, end: 0.0).animate(animController)
..addListener(() {
setState(() {});
});

// TODO: implement initState
super.initState();
_scrollController = ScrollController()
..addListener(() {
if (_scrollController.offset.toInt() >= 283 && monhani == true) {
setState(() {
animController.forward();
monhani=false;
});
} else if(_scrollController.offset.toInt() <= 283) {
animController.reverse();
monhani=true;
}
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.lightBlue[100],
body: CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverAppBar(
bottom: PreferredSize(
child: Container(
color: Colors.orange,
),
preferredSize: Size(0, 60),
),
pinned: true,
expandedHeight: 400,
automaticallyImplyLeading: true,
primary: false,
flexibleSpace: Stack(
children: <Widget>[
Center(
child: Container(
height: 400,
width: 450,
decoration: BoxDecoration(
// color: Colors.green,
image: DecorationImage(
image: NetworkImage(
"https://images.pexels.com/photos/62389/pexels-photo-
62389.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"),
fit: BoxFit.cover)),
),
),
Positioned(
child: Container(
height: 100,
decoration: BoxDecoration(
color: Colors.lightBlue[100],
borderRadius: BorderRadius.only(
topLeft: Radius.circular(animation.value)),
),
),
bottom: -1,
left: 0,
right: 0,
),
],
),
),
SliverList(
delegate: SliverChildListDelegate([
Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height - 100,
width: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(animation.value)),
),
),
Container(
height: MediaQuery.of(context).size.height - 100,
width: double.infinity,
alignment: Alignment.center,
color: Colors.green,
),
Container(
height: MediaQuery.of(context).size.height - 100,
width: double.infinity,
alignment: Alignment.center,
color: Colors.amber,
),
],
)
]),
),
],
),
);
}
}
[this image is result][1]


[1]:
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through