在 Flutter 中,如果我想要任意图像覆盖 300x300 的空间,我可以使用 SizedBox 和 FittedBox 来实现:
SizedBox(
height: 300,
width: 300,
child: FittedBox(
fit: BoxFit.cover,
clipBehavior: Clip.hardEdge,
child: Image.network(landscapeImage),
),
),
图像将尽可能小,同时仍然完全覆盖 300x300 容器。 (图像的宽高比没有改变,图像中不适合容器的额外部分被剪掉了。除了用视频而不是图像,我怎样才能完成同样的事情?我最近的尝试基本上是:
SizedBox(
height: 300,
width: 300,
child: FittedBox(
fit: BoxFit.cover,
clipBehavior: Clip.hardEdge,
child: videoPlayerController.value.isInitialized
? SizedBox(
height: 300,
width: 300,
child: AspectRatio(
aspectRatio: aspectRatio,
child: VideoPlayer(videoPlayerController),
),
)
: const CircularProgressIndicator(),
),
),
然而,这最终导致视频的宽高比无法保持。这是我的全部代码:
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Square Video',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
const landscapeVideo = 'https://userbob.com/landscape.mp4';
const portraitVideo = 'https://userbob.com/portrait.mp4';
const landscapeImage = 'https://userbob.com/landscape.png';
const portraitImage = 'https://userbob.com/portrait.png';
class _MyHomePageState extends State<MyHomePage> {
late VideoPlayerController videoPlayerController;
double aspectRatio = 1;
@override
void initState() {
super.initState();
videoPlayerController = VideoPlayerController.network(portraitVideo);
videoPlayerController.initialize().then((_) {
setState(() {
aspectRatio = videoPlayerController.value.aspectRatio;
print('aspectRatio = $aspectRatio');
});
});
}
@override
void dispose() {
videoPlayerController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
print('building aspectRatio=$aspectRatio');
return Scaffold(
appBar: AppBar(
title: const Text('Video Covering a Square'),
),
body: SizedBox(
height: 300,
width: 300,
child: FittedBox(
fit: BoxFit.cover,
clipBehavior: Clip.hardEdge,
child: videoPlayerController.value.isInitialized
? SizedBox(
height: 300,
width: 300,
child: AspectRatio(
aspectRatio: aspectRatio,
child: VideoPlayer(videoPlayerController),
),
)
: const CircularProgressIndicator(),
),
),
);
}
}