Dol*_*rma 4 dart flutter flutter-layout
如何Container在ListView向下滚动时显示动画并在向上滚动时隐藏它。
我附上的视频并不是我想要的确切实现,只是为了给您一个想法。
示例视频
编辑:
每次向下滚动时,我都需要显示Container,每次向上滚动时,我都想隐藏它。它不应该依赖于ListView.
Cop*_*oad 12
不确定我是否正确回答了您的问题,这是您要实现的目标吗?
截屏:
代码:
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// Height of your Container
static final _containerHeight = 100.0;
// You don't need to change any of these variables
var _fromTop = -_containerHeight;
var _controller = ScrollController();
var _allowReverse = true, _allowForward = true;
var _prevOffset = 0.0;
var _prevForwardOffset = -_containerHeight;
var _prevReverseOffset = 0.0;
@override
void initState() {
super.initState();
_controller.addListener(_listener);
}
// entire logic is inside this listener for ListView
void _listener() {
double offset = _controller.offset;
var direction = _controller.position.userScrollDirection;
if (direction == ScrollDirection.reverse) {
_allowForward = true;
if (_allowReverse) {
_allowReverse = false;
_prevOffset = offset;
_prevForwardOffset = _fromTop;
}
var difference = offset - _prevOffset;
_fromTop = _prevForwardOffset + difference;
if (_fromTop > 0) _fromTop = 0;
} else if (direction == ScrollDirection.forward) {
_allowReverse = true;
if (_allowForward) {
_allowForward = false;
_prevOffset = offset;
_prevReverseOffset = _fromTop;
}
var difference = offset - _prevOffset;
_fromTop = _prevReverseOffset + difference;
if (_fromTop < -_containerHeight) _fromTop = -_containerHeight;
}
setState(() {}); // for simplicity I'm calling setState here, you can put bool values to only call setState when there is a genuine change in _fromTop
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("ListView")),
body: Stack(
children: <Widget>[
_yourListView(),
Positioned(
top: _fromTop,
left: 0,
right: 0,
child: _yourContainer(),
)
],
),
);
}
Widget _yourListView() {
return ListView.builder(
itemCount: 100,
controller: _controller,
itemBuilder: (_, index) => ListTile(title: Text("Item $index")),
);
}
Widget _yourContainer() {
return Opacity(
opacity: 1 - (-_fromTop / _containerHeight),
child: Container(
height: _containerHeight,
color: Colors.red,
alignment: Alignment.center,
child: Text("Your Container", style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold, color: Colors.white)),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 11
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
const double HEIGHT = 96;
final ValueNotifier<double> notifier = ValueNotifier(0);
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: const Text('Test')),
body: Stack(
children: [
NotificationListener<ScrollNotification>(
onNotification: (n) {
if (n.metrics.pixels <= HEIGHT) {
notifier.value = n.metrics.pixels;
}
return false;
},
child: ListView.builder(
itemCount: 42,
itemBuilder: (context, index) {
return Container(
height: 64,
padding: const EdgeInsets.all(16),
alignment: Alignment.centerLeft,
child: Text('Item $index'),
);
},
),
),
HideableWidget(height: HEIGHT, notifier: notifier),
],
),
),
);
}
}
class HideableWidget extends StatelessWidget {
final double height;
final ValueNotifier<double> notifier;
HideableWidget({@required this.height, @required this.notifier});
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<double>(
valueListenable: notifier,
builder: (context, value, child) {
return Transform.translate(
offset: Offset(0, value - height),
child: Container(
height: 80,
color: Colors.red,
),
);
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4925 次 |
| 最近记录: |