Изменить размер / положение текста относительно другого виджета - PullRequest
1 голос
/ 26 января 2020

Кто-нибудь может помочь?

В настоящее время текст, который я отображаю поверх видео, имеет фиксированный размер и положение.

Мне интересно, как я могу изменить это динамически / быстро соответствует размеру родительского виджета (видео).

Я попробовал метод с использованием 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();
  }
}

Ответы [ 2 ]

1 голос
/ 27 января 2020

LayoutBuilder может предоставить вам свойства width и height, соответствующие текущему доступному пространству. Проверьте эту документацию здесь . Он предоставляет сборщику экземпляр BoxConstraints, как в здесь . Вы можете использовать эту информацию для изменения размера текста.

Проверьте Align виджет . Он может поместить дочерний элемент в указанное c местоположение в системе координат родительского виджета. В вашем случае это будут координаты виджета Stack.

Я бы попробовал что-то вроде следующего.

  1. Оберните виджет Text внутри Align виджет и используйте FractionalOffset для размещения выравнивания виджета. Вы также можете напрямую использовать экземпляр Alignment. Происхождение будет отличаться для обоих подходов. Проверьте документы здесь
  2. Затем оберните мой 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();
  }
}
0 голосов
/ 26 января 2020

Он легко доступен через MediaQuery.of(context).size ( Документация ).

Помните, что вы должны вызывать внутри вашего метода сборки, так как он требует контекста

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...