Flutter 显示 ListView 顶部的渐变分隔线
Flutter show gradient Divider top of ListView
在这个具有 ListView
和 Container
的示例代码中,当用户向右或向左滚动 ListView 项目时,我想在 ListView
的顶部制作简单的渐变,
向右滚动项目应该显示渐变分隔线,向左滚动应该隐藏分隔线,所有这些可见性应该有淡入淡出的效果,你能帮我看看如何显示和隐藏这个渐变分隔线吗?
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(SampleShadow());
class SampleShadow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'sample',
home: ShadowContainer(),
);
}
}
class ShadowContainer extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ShadowContainer();
}
class _ShadowContainer extends State<ShadowContainer> with TickerProviderStateMixin {
final ValueNotifier<bool> showShadow = ValueNotifier<bool>(false);
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
backgroundColor: Colors.indigo.withOpacity(0.7),
appBar: AppBar(),
body: Container(
margin: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: 100.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
color: Colors.indigo[400],
borderRadius: BorderRadius.circular(100.0),
),
),
Expanded(
child: Stack(children: <Widget>[
NotificationListener<ScrollNotification>(
onNotification: (scrollState) {
if (scrollState is ScrollEndNotification && scrollState.metrics.pixels >= 100) {
showShadow.value = true;
print('show');
} else {
showShadow.value = false;
print('hide');
}
return false;
},
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.all(10.0),
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
color: Colors.purple[400],
borderRadius: BorderRadius.circular(100.0),
),
);
},
separatorBuilder: (context, index) {
return const Divider();
},
itemCount: 50),
),
ValueListenableBuilder<bool>(
valueListenable: showShadow,
builder: (context, value, child) => value? Container(
width: 10.0,
color: Colors.green,
): Container()),
]),
),
],
),
),
],
),
),
),
);
}
}
由于 @CopsOnRoad
,此解决方案工作正常
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(SampleShadow());
class SampleShadow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'sample',
home: ShadowContainer(),
);
}
}
class ShadowContainer extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ShadowContainer();
}
class _ShadowContainer extends State<ShadowContainer> with TickerProviderStateMixin {
final ValueNotifier<bool> showShadow = ValueNotifier<bool>(false);
AnimationController _animationController;
Animation<double> _fadeInFadeOut;
ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_animationController = AnimationController(vsync: this, duration: kThemeAnimationDuration);
_fadeInFadeOut = Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
_animationController.forward();
_scrollController.addListener(() {
if (_scrollController.offset >= 10) {
showShadow.value = true;
} else {
showShadow.value = false;
}
});
}
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
backgroundColor: Colors.indigo.withOpacity(0.7),
appBar: AppBar(),
body: Container(
margin: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: 100.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
color: Colors.indigo[400],
borderRadius: BorderRadius.circular(100.0),
),
),
Expanded(
child: Stack(children: <Widget>[
ListView.separated(
controller: _scrollController,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.all(10.0),
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
color: Colors.purple[400],
borderRadius: BorderRadius.circular(100.0),
),
);
},
separatorBuilder: (context, index) {
return const Divider();
},
itemCount: 50),
ValueListenableBuilder<bool>(
valueListenable: showShadow,
builder: (context, value, child) {
if (value) {
_animationController.forward();
} else {
_animationController.reverse();
}
return FadeTransition(
opacity: _fadeInFadeOut,
child: Container(
width: 10.0,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerRight,
end: Alignment.centerLeft,
colors: [Colors.black.withOpacity(0.5), Colors.transparent])),
),
);
}),
]),
),
],
),
),
],
),
),
),
);
}
}
在这个具有 ListView
和 Container
的示例代码中,当用户向右或向左滚动 ListView 项目时,我想在 ListView
的顶部制作简单的渐变,
向右滚动项目应该显示渐变分隔线,向左滚动应该隐藏分隔线,所有这些可见性应该有淡入淡出的效果,你能帮我看看如何显示和隐藏这个渐变分隔线吗?
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(SampleShadow());
class SampleShadow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'sample',
home: ShadowContainer(),
);
}
}
class ShadowContainer extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ShadowContainer();
}
class _ShadowContainer extends State<ShadowContainer> with TickerProviderStateMixin {
final ValueNotifier<bool> showShadow = ValueNotifier<bool>(false);
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
backgroundColor: Colors.indigo.withOpacity(0.7),
appBar: AppBar(),
body: Container(
margin: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: 100.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
color: Colors.indigo[400],
borderRadius: BorderRadius.circular(100.0),
),
),
Expanded(
child: Stack(children: <Widget>[
NotificationListener<ScrollNotification>(
onNotification: (scrollState) {
if (scrollState is ScrollEndNotification && scrollState.metrics.pixels >= 100) {
showShadow.value = true;
print('show');
} else {
showShadow.value = false;
print('hide');
}
return false;
},
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.all(10.0),
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
color: Colors.purple[400],
borderRadius: BorderRadius.circular(100.0),
),
);
},
separatorBuilder: (context, index) {
return const Divider();
},
itemCount: 50),
),
ValueListenableBuilder<bool>(
valueListenable: showShadow,
builder: (context, value, child) => value? Container(
width: 10.0,
color: Colors.green,
): Container()),
]),
),
],
),
),
],
),
),
),
);
}
}
由于 @CopsOnRoad
,此解决方案工作正常import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(SampleShadow());
class SampleShadow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'sample',
home: ShadowContainer(),
);
}
}
class ShadowContainer extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ShadowContainer();
}
class _ShadowContainer extends State<ShadowContainer> with TickerProviderStateMixin {
final ValueNotifier<bool> showShadow = ValueNotifier<bool>(false);
AnimationController _animationController;
Animation<double> _fadeInFadeOut;
ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_animationController = AnimationController(vsync: this, duration: kThemeAnimationDuration);
_fadeInFadeOut = Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
_animationController.forward();
_scrollController.addListener(() {
if (_scrollController.offset >= 10) {
showShadow.value = true;
} else {
showShadow.value = false;
}
});
}
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
backgroundColor: Colors.indigo.withOpacity(0.7),
appBar: AppBar(),
body: Container(
margin: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: 100.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
color: Colors.indigo[400],
borderRadius: BorderRadius.circular(100.0),
),
),
Expanded(
child: Stack(children: <Widget>[
ListView.separated(
controller: _scrollController,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.all(10.0),
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
color: Colors.purple[400],
borderRadius: BorderRadius.circular(100.0),
),
);
},
separatorBuilder: (context, index) {
return const Divider();
},
itemCount: 50),
ValueListenableBuilder<bool>(
valueListenable: showShadow,
builder: (context, value, child) {
if (value) {
_animationController.forward();
} else {
_animationController.reverse();
}
return FadeTransition(
opacity: _fadeInFadeOut,
child: Container(
width: 10.0,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerRight,
end: Alignment.centerLeft,
colors: [Colors.black.withOpacity(0.5), Colors.transparent])),
),
);
}),
]),
),
],
),
),
],
),
),
),
);
}
}