Zero, preface,
If you’ve ever been to FlutterUnit, the Tap bar in the header of the home page should have impressed you. The Tap bar becomes progressively shorter as you slide up to a minimum. When the Tap bar is pulled down to the top, the Tap bar becomes progressively higher until the maximum value FlutterUnit itself has a complex home page. In this article, I will write a minimalist practice that uses the least amount of code to achieve this effect. SliverPersistentHeader
Slide effect | The drop-down effect |
---|---|
I. Initial project
1. Program entry
In the main function using SystemChrome. SetSystemUIOverlayStyle make the status bar is transparent
Core components in SliverPersistentHeaderDemo test demo
void main() {
// Set the transparent status bar
SystemUiOverlayStyle style = SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(style);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue ), home: Scaffold( body: SliverPersistentHeaderDemo(), )); }}Copy the code
2. Build a color list
We’re going to build a more sophisticated sliding effect, using a CustomScrollView where slivers receive a list of Sliver family components. CustomScrollView is not the subject of this article, but will be covered later. _buildSliverList is responsible for building SliverList, where the buildColor item component is left to _buildColorItem. I recommend that you break down the granularity of your build, rather than trying to put everything in one piece, so it looks clearer.
Color list | Color list |
---|---|
class SliverPersistentHeaderDemo extends StatelessWidget {
// Color data
final List<Color> data = List.generate(24, (i) => Color(0xFFFF00FF - 24*i));
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
// TODO adds bar
_buildSliverList()
],
);
}
// Build a list of colors
Widget _buildSliverList() =>
SliverList(
delegate: SliverChildBuilderDelegate(
(_, int index) => _buildColorItem(data[index]),
childCount: data.length),
);
// Build the color list item
Widget _buildColorItem(Color color) =>
Card(
child: Container(
alignment: Alignment.center,
width: 100,
height: 60,
color: color,
child: Text(
colorString(color),
style: const TextStyle(
color: Colors.white,
shadows: [
Shadow(color: Colors.black,
offset: Offset(. 5.. 5),
blurRadius: 2() [(), ((), (();// Color is converted to text
String colorString(Color color) =>
"#${color.value.toRadixString(16).padLeft(8.'0').toUpperCase()}";
}
Copy the code
Now that the initial demo is set up, let’s see how SliverPersistentHeader is used
Second, knowSliverPersistentHeader
1.SliverPersistentHeader
Properties in
The property name | type | The default value | introduce |
---|---|---|---|
delegate | SliverPersistentHeaderDelegate | required | Component build agent |
pinned | bool | false | Whether fixed |
floating | bool | false | Whether floating |
2.SliverPersistentHeaderDelegate
The use of
I’m sure a lot of people look at XXXDelegate and feel dissuaded. Don’t be afraid. Let’s see what it is. We can see that it’s an abstract class, so we need to implement some abstract method, and an abstract method is always going to call back something of value and look at its family tree and see that there’s no subclass that we can use, so if we want to use it, we need to write a subclass.
Now write a UnitPersistentHeaderDelegate implement SliverPersistentHeaderDelegate, can see there are the following four methods: need to implement build,maxExtent,minExtent,shouldRebuild
class UnitPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
print(
"=====shrinkOffset:$shrinkOffset======overlapsContent:$overlapsContent= = = =");
final String info =
'shrinkOffset:${shrinkOffset.toStringAsFixed(1)}'
'\noverlapsContent:$overlapsContent';
return Container(
alignment: Alignment.center,
color: Colors.orangeAccent,
child: Text(
info,
style: TextStyle(fontSize: 20, color: Colors.white),
),
);
}
@override
double get maxExtent => 120;
@override
double get minExtent => 80;
@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) =>
false;
}
Copy the code
Give me a little simple implementation using the above definition of UnitPersistentHeaderDelegate view effect: As you can see, the build method above is used to build components with shrinkOffset in the header. The components begin to expand the maxExtent height fully as they slide up the list. You can see from the log that the maximum slide height is maxExtent, which is the default pinned=false,floating=false slide effect.
Slide the test | The tensile test |
---|---|
// The hero sees...
return CustomScrollView(
slivers: <Widget>[
_buildPersistentHeader(), PersistentHeader is created above the list
_buildSliverList()
],
);
}
/ / use UnitPersistentHeaderDelegate PersistentHeader creation
Widget _buildPersistentHeader() => SliverPersistentHeader(
delegate: UnitPersistentHeaderDelegate());
Copy the code
3. SliverPersistentHeaderPinned with floating
attribute
Here’s the test:
pinned_true_floating_false | pinned_true_floating_true |
---|---|
Skidding up: The minExtent height is left at the top and does not decrease with skidding up | Skidding up: The minExtent height is left at the top and does not decrease with skidding up |
Pull down: The remaining space does not unfold until you reach the top | Drop down: When you drop down from any position, the remaining space expands |
Here’s the test:
pinned_false_floating_false | pinned_false_floating_true |
---|---|
Slide up: The top slides out | Slide up: The top slides out |
Pull down: The top does not unfold until you reach the top | Drop down: Space expands when you drop down from any position |
Three, use,SliverPersistentHeader
1. Wrap PersistentHeaderBuilder
The persistenThebuilder is a custom builder that simplifies the build
Using the Builder property, you can call back some valuable data, such as offsets, when you hand over the created logic to use
class PersistentHeaderBuilder extends SliverPersistentHeaderDelegate {
final double max;
final double min;
final Widget Function(BuildContext context, double offset) builder;
PersistentHeaderBuilder(
{this.max = 120.this.min = 80.@required this.builder})
: assert(max >= min && builder ! =null);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return builder(context, shrinkOffset);
}
@override
double get maxExtent => max;
@override
double get minExtent => min;
@override
bool shouldRebuild(covariantPersistentHeaderBuilder oldDelegate) => max ! = oldDelegate.max || min ! = oldDelegate.min || builder ! = oldDelegate.builder; }Copy the code
2. Use PersistentHeaderBuilder
Widget _buildPersistentHeader() => SliverPersistentHeader(
pinned: true,
floating: false,
delegate: PersistentHeaderBuilder(builder: (ctx, offset) => Container(
alignment: Alignment.center,
color: Colors.orangeAccent,
child: Text(
"shrinkOffset:${offset.toStringAsFixed(1)}",
style: TextStyle(fontSize: 20, color: Colors.white),
),
)));
Copy the code
3. Use of multiple SliverPersistentHeader
You can also do some transformations based on offset. Multiple SliverPersistentHeader can coexist, as shown below
slide | The drop-down |
---|---|
Widget _buildPersistentHeader2() => SliverPersistentHeader(
pinned: false,
floating: false,
delegate: PersistentHeaderBuilder(
max: 100,
builder: (ctx, offset) => Container(
transform: Matrix4.rotationZ(offset / 120 * pi / 2),
alignment: Alignment.center,
color: Colors.blue,
child: Text(
"shrinkOffset:${offset.toStringAsFixed(1)}",
style: TextStyle(fontSize: 20, color: Colors.white),
),
)));
Copy the code
This is the basic usage of SliverPersistentHeader, and you can achieve many interesting sliding effects based on it. Finally, welcome to my open source project FlutterUnit. There will be more articles about FlutterUnit, including the use of Flutter components. FlutterUnit implementation details, major updates to FlutterUnit, etc.
@Zhangfengjietele 2020.10.25 not allowed to transfer ~ END ~