可滚动的背景图像

问题描述 投票:1回答:1

我正在尝试实现可滚动的背景图像(视差)。就像在主屏幕启动器中一样。

一个例子:在Evie启动器中:this video

我曾尝试使用AnimatedBuilder在此类文档中提到的here

我正在使用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.asset(
                   "assets/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变为零之前存储值,并在它返回零时使用它,但导致了上面视频中向您展示的怪异转换。

您建议怎么做才能使像可滚动墙纸一样颤动?

这样的东西

Design

image flutter flutter-animation
1个回答
0
投票

这不简单。

© www.soinside.com 2019 - 2024. All rights reserved.