【发布时间】:2019-10-17 17:19:24
【问题描述】:
我正在尝试实现可滚动的背景图像(视差)。 就像在主屏幕启动器中一样。
一个例子: 在 Evie 启动器中: this video
我已经尝试使用 AnimatedBuilder 在像这样的文档中提到 here。
我使用ValueNotifier<double> 作为 AnimatedBuilder Widget 动画的监听器。
完整的代码是这样的
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'PageView Scrolling',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>{
ValueNotifier<double> _notifier;
double _prevnotifier;
double getOffset(){
if (_notifier.value == 0 && _prevnotifier != null){
return _prevnotifier;
}
return _notifier.value;
}
@override
void dispose() {
_notifier?.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
_notifier = ValueNotifier<double>(0);
_prevnotifier = _notifier.value;
_notifier.addListener(
(){
print('object ${_notifier.value}');
if (_notifier.value != 0)
_prevnotifier = _notifier.value;
}
);
}
@override
Widget build(BuildContext context) {
print("Size is ${MediaQuery.of(context).size}");
return Scaffold(
body: Stack(
children: <Widget>[
AnimatedBuilder(
animation: _notifier,
builder: (context, _) {
return Transform.translate(
offset: Offset(-getOffset() * 60, 0),
child: Image.network(
"https://w.wallhaven.cc/full/r2/wallhaven-r276qj.png",
height: MediaQuery.of(context).size.height,
fit: BoxFit.fitHeight
),
);
},
),
NotifyingPageView(
notifier: _notifier,
),
],
),
);
}
}
class NotifyingPageView extends StatefulWidget {
final ValueNotifier<double> notifier;
const NotifyingPageView({Key key, this.notifier}) : super(key: key);
@override
_NotifyingPageViewState createState() => _NotifyingPageViewState();
}
class _NotifyingPageViewState extends State<NotifyingPageView> {
int _previousPage;
PageController _pageController;
void _onScroll() {
// Consider the page changed when the end of the scroll is reached
// Using onPageChanged callback from PageView causes the page to change when
// the half of the next card hits the center of the viewport, which is not
// what I want
if (_pageController.page.toInt() == _pageController.page) {
_previousPage = _pageController.page.toInt();
}
widget.notifier?.value = _pageController.page - _previousPage;
}
@override
void initState() {
_pageController = PageController(
initialPage: 0,
viewportFraction: 0.9,
)..addListener(_onScroll);
_previousPage = _pageController.initialPage;
super.initState();
}
List<Widget> _pages = List.generate(
10,
(index) {
return Container(
height: 10,
alignment: Alignment.center,
color: Colors.transparent,
child: Text(
"Card number $index",
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
);
},
);
@override
Widget build(BuildContext context) {
return PageView(
children: _pages,
controller: _pageController,
);
}
}
图片可以找到here
现在我有两个问题:
- 使用
fit: BoxFit.fitHeight时的图像没有完全溢出。目前就像this - 因为动画完成后该值将变为零,所以它会像这样捕捉: this video
我尝试在 _notifier.value 变为零之前存储该值,并在它返回零时使用它,但它导致了我在上面的视频中向您展示的那种奇怪的过渡。
你建议可以做些什么来制作类似可滚动壁纸的东西?
类似的东西
【问题讨论】:
-
我Phani,我已经回答了你打开的问题! github.com/magicleon94/pagaview_scrolling/issues/1
标签: image flutter flutter-animation