我正在尝试实现可滚动的背景图像(视差)。就像在主屏幕启动器中一样。
示例:在Evie启动器中:该视频
我试着用AnimatedBuilder
提到这里在这样的文档。
我正在将ValueNotifier<double>
用作AnimatedBuilder小部件的动画的侦听器。
完整的代码是这个
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,
);
}
}
图像可以在这里找到
现在我有两个问题:
我试过在_notifier.value
变成零之前存储值,并在它返回零时使用它,但这导致了上面视频中向您展示的怪异转换。
您认为可以做些什么来使像可滚动墙纸一样颤动?
像这样
这并不像我想的那么简单。
TLDR ; Github阅读了评论。
我使用了ValueNotifier<double>
我提到的控件来控制滚动。
然后,与其Transform.translate
使用我的属性。这是基于渲染前计算的。OverflowBox
alignment
notifier.value
并以全屏模式显示图像:
我曾经AspectRatio
有个孩子DecoratedBox
,其decoration
是BoxDecoration
与它image
作为ImageProvider
。
所有的代码,可以发现这里在GitHub上。(阅读评论)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句