【问题标题】:Flutter. How can I make container wider than screen?扑。如何使容器比屏幕宽?
【发布时间】:2019-09-02 14:11:45
【问题描述】:

我正在尝试为页面控制器创建视差背景。为此,我需要创建一个比屏幕宽的背景图像。我把它放在这样的容器里:

@override
  Widget build(BuildContext context) {

    return Material(
      child: Stack(
        children: [
          Container(
              width: 4000,
              height:  250,
              decoration: BoxDecoration(
                  image: DecorationImage(
                      image: AssetImage('assets/images/pizza_bg.png'),
                      fit: BoxFit.cover,
                      repeat: ImageRepeat.noRepeat
                  )
              )
          ),
        ],
      ),
    );
  }

但问题是,无论我指定什么宽度,容器(当然还有图像)永远不会比屏幕宽。有可能吗? p.s.我尝试使用 SizedBox 和 AspectRatio 小部件,它们都给出相同的结果

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    试试这个,作为一个选项

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Stack(
              children: [
                SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: Container(
                    width: 4000,
                    height: 250,
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        image: AssetImage('assets/images/pizza_bg.png'),
                        fit: BoxFit.cover,
                        repeat: ImageRepeat.noRepeat,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    

    您也可以为用户禁用滚动并通过滚动控制器管理滚动位置

        SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          physics: const NeverScrollableScrollPhysics(),
          controller: controller, // your ScrollController
          child: Container(
            width: 4000,
            height: 250,
            decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage('images/pizza_bg.png'),
                fit: BoxFit.cover,
                repeat: ImageRepeat.noRepeat,
              ),
            ),
          ),
        ),
    

    【讨论】:

    • 它有效,谢谢!我会尝试了解 SingleChildScrollView 的工作方式
    • 我看到你已经编辑了你的答案。是的,我从一开始就使用控制器。它基本上只是将图像移动到计算出的距离,以使效果看起来像视差。它完全按照我的需要工作:)
    【解决方案2】:

    对于图像,您可以使用Transform.scale(),如documentation 中所示。使用您的示例:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Stack(
              children: [
                Align(
                  alignment: Alignment.center,
                  child: Transform.scale(
                    scale: 10.0,
                    child: Container(
                      width: 400,
                      height: 25,
                      decoration: BoxDecoration(
                        image: DecorationImage(
                          image: AssetImage('assets/images/pizza_bg.png'),
                          fit: BoxFit.cover,
                          repeat: ImageRepeat.noRepeat,
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    

    如果要为比例设置动画,可以使用ScaleTransition()explained in this page of the docs。例如:

    /// Flutter code sample for ScaleTransition
    
    // The following code implements the [ScaleTransition] as seen in the video
    // above:
    
    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    /// This is the main application widget.
    class MyApp extends StatelessWidget {
      static const String _title = 'Flutter Code Sample';
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: _title,
          home: MyStatefulWidget(),
        );
      }
    }
    
    /// This is the stateful widget that the main application instantiates.
    class MyStatefulWidget extends StatefulWidget {
      MyStatefulWidget({Key key}) : super(key: key);
    
      @override
      _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
    }
    
    /// This is the private State class that goes with MyStatefulWidget.
    /// AnimationControllers can be created with `vsync: this` because of TickerProviderStateMixin.
    class _MyStatefulWidgetState extends State<MyStatefulWidget>
        with TickerProviderStateMixin {
      AnimationController _controller;
      Animation<double> _animation;
    
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(
          duration: const Duration(seconds: 2),
          vsync: this,
        )..repeat(reverse: true);
        _animation = CurvedAnimation(
          parent: _controller,
          curve: Curves.fastOutSlowIn,
        );
      }
    
      @override
      void dispose() {
        super.dispose();
        _controller.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: ScaleTransition(
              scale: _animation,
              child: const Padding(
                padding: EdgeInsets.all(8.0),
                child: FlutterLogo(size: 150.0),
              ),
            ),
          ),
        );
      }
    }
    

    注意:为避免图像质量损失,请使用缩放后大小的图像或矢量图形作为来源。

    【讨论】:

    • 这不是一个好的解决方案,因为如果图像不是矢量,缩放会破坏质量
    • 但是,如果源图像的大小是由缩放因子 * 初始大小产生的,则不会丢失质量,如我回答中的示例所示。我刚才检查过了。我会添加一个建议。
    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 2014-03-27
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    相关资源
    最近更新 更多