相对于其他窗口小部件更改文本的大小/位置

问题描述 投票:0回答:2

任何人都可以帮忙吗?

当前,我在视频上显示的文本具有固定的大小和位置。

我想知道如何动态/响应地更改它以匹配其父窗口小部件(视频)的大小。

[我尝试了使用GlobalKey的方法,但出现错误,我认为是因为视频尚未加载。。

text over a video

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      drawer: ResponsiveLayout.isSmallScreen(context) ? NavDrawer() : null,
      body: Container(
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              NavBar(),
              Body(),
              Footer(),
            ],
          ),
        ),
      ),
    );
  }
}

class Body extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ResponsiveLayout(
      largeScreen: LargeScreen(),
      mediumScreen: LargeScreen(),
      smallScreen: LargeScreen(),
    );
  }
}

class LargeScreen extends StatefulWidget {
  @override
  _LargeScreenState createState() => _LargeScreenState();
}

class _LargeScreenState extends State<LargeScreen> {
  VideoPlayerController _videoPlayerController;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    _videoPlayerController = VideoPlayerController.asset(
      'assets/videos/video.mp4',
    );
    _initializeVideoPlayerFuture = _videoPlayerController.initialize();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 40),
      child: Column(
        children: <Widget>[
          FutureBuilder(
            future: _initializeVideoPlayerFuture,
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done &&
                  !_videoPlayerController.value.isBuffering) {
                // If the VideoPlayerController has finished initialization, use
                // the data it provides to limit the aspect ratio of the VideoPlayer.
                return AspectRatio(
                  aspectRatio: _videoPlayerController.value.aspectRatio,
                  // Use the VideoPlayer widget to display the video.
                  child: Stack(
                    children: <Widget>[
                      VideoPlayer(_videoPlayerController),
                      Positioned(
                        bottom: 20,
                        left: 20,
                        child: FittedBox(
                          child: Text(
                            'Text over\na video',
                            style: TextStyle(
                                color: Colors.white,
                                fontSize:50),
                          ),
                        ),
                      )
                    ],
                  ),
                );
              } else {
                // If the VideoPlayerController is still initializing, show a
                // loading spinner.
                return Center(child: CircularProgressIndicator());
              }
            },
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _videoPlayerController.dispose();
  }
}
flutter dart flutter-layout flutter-web
2个回答
0
投票

可通过MediaQuery.of(context).sizeDocumentation)轻松访问。

请记住,由于它需要上下文,因此必须在内部构建方法中调用


0
投票

LayoutBuilder可以为您提供widthheight属性,它们与当前可用空间相对应。检查此文档here。像BoxConstraints一样,它为构建器提供了here实例。您可以使用此信息来调整文字大小。

检查Align widget。可以将孩子放置在父小部件的坐标系统内的特定位置。在您的情况下,它将位于Stack小部件的坐标上。

我会尝试以下类似方法。1.将Text小部件包装在Align小部件内,然后使用FractionalOffset放置对齐小部件。您也可以直接使用Alignment实例。两种方法的来源都会有所不同。检查文档here2.然后将我的Align小部件包装在LayoutBuilder小部件中,以获取可用大小并根据其确定我的字体大小。类似于fontSize: constraints.maxWidth / 25

下面是示例工作代码。

// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      // drawer: ResponsiveLayout.isSmallScreen(context) ? NavDrawer() : null,
      body: Container(
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              // NavBar(),
              Body(),
              // Footer(),
            ],
          ),
        ),
      ),
    );
  }
}

class Body extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // return ResponsiveLayout(
    //   largeScreen: LargeScreen(),
    //   mediumScreen: LargeScreen(),
    //   smallScreen: LargeScreen(),
    // );
    return LargeScreen();
  }
}

class LargeScreen extends StatefulWidget {
  @override
  _LargeScreenState createState() => _LargeScreenState();
}

class _LargeScreenState extends State<LargeScreen> {
  VideoPlayerController _videoPlayerController;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    _videoPlayerController = VideoPlayerController.network(
      'http://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4',
    );
    _initializeVideoPlayerFuture =
        _videoPlayerController.initialize().then((onValue) {
      setState(() {});
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 40),
      child: Column(
        children: <Widget>[
          FutureBuilder(
            future: _initializeVideoPlayerFuture,
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done &&
                  !_videoPlayerController.value.isBuffering) {
                // If the VideoPlayerController has finished initialization, use
                // the data it provides to limit the aspect ratio of the VideoPlayer.
                return AspectRatio(
                  aspectRatio: _videoPlayerController.value.aspectRatio,
                  // Use the VideoPlayer widget to display the video.
                  child: Stack(
                    children: <Widget>[
                      VideoPlayer(_videoPlayerController),
                      LayoutBuilder(
                        builder: (context, constraints) {
                          return Align(
                            // this decides the position of the text.
                            alignment: FractionalOffset(0.05, 0.95),
                            child: FittedBox(
                              child: Text(
                                'Text over\na video',
                                style: TextStyle(
                                  color: Colors.white,
                                  // here font size is ratio of the maxwidth available for this widget.
                                  fontSize: constraints.maxWidth / 25,
                                ),
                              ),
                            ),
                          );
                        },
                      )
                    ],
                  ),
                );
              } else {
                // If the VideoPlayerController is still initializing, show a
                // loading spinner.
                return Center(child: CircularProgressIndicator());
              }
            },
          ),
          FloatingActionButton(
            onPressed: () {
              setState(() {
                _videoPlayerController.value.isPlaying
                    ? _videoPlayerController.pause()
                    : _videoPlayerController.play();
              });
            },
            child: Icon(
              _videoPlayerController.value.isPlaying
                  ? Icons.pause
                  : Icons.play_arrow,
            ),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _videoPlayerController.dispose();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.