如何在 Flutter 中 "center crop" 一个 Widget?
How can you "center crop" a Widget in Flutter?
我有一个 VideoPlayer 小部件,它需要全屏显示并且适合源视频的纵横比。为了实现这一点,我需要删除视频的 top/bottom 或 left/right。
我曾希望以下方法可以实现此目的,但我认为我一定是使用 FittedBox
不正确,因为它导致我的 VideoPlayer
消失:
final Size size = controller.value.size;
return new FittedBox(
fit: BoxFit.cover,
child: new AspectRatio(
aspectRatio: size.width / size.height,
child: new VideoPlayer(controller)
),
);
谁能帮我解决这个问题?
终于解决了。有一些缺失的部分:
- 我需要一个没有限制的
OverflowBox
,这样我的 child 就可以根据需要变大。
- 我需要
FittedBox
的 child 来实际强制执行大小以防止布局系统崩溃。
- 现在我的小部件将在其边界之外绘制,我们还想在其中放置一个
ClipRect
以阻止这种情况发生。
final Size size = controller.value.size;
return new ClipRect(
child: new OverflowBox(
maxWidth: double.infinity,
maxHeight: double.infinity,
alignment: Alignment.center,
child: new FittedBox(
fit: BoxFit.cover,
alignment: Alignment.center,
child: new Container(
width: size.width,
height: size.height,
child: new VideoPlayer(controller)
)
)
)
);
我遇到了很多问题,接受的答案并没有为我解决。我只是想让背景图像垂直放置并水平溢出。以下是我最终的做法:
OverflowBox(
maxWidth: double.infinity,
alignment: Alignment.center,
child:
Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
UnconstrainedBox(
constrainedAxis: Axis.vertical,
child: Image.asset('images/menu_photo_1.jpg', fit: BoxFit.cover))
])
)
我知道这个问题很老了,但我在这里 post 所以如果其他人找到它,他们会找到另一个解决方案。所以基本上,如果您总是想要一张图片覆盖一个区域,但又想始终显示图片的中间(我猜是中心裁剪),请在图片周围创建一个 sizedbox。您可能会说它没有响应或必须进行硬编码。只是从一些东西来计算它。我确实喜欢:
class HomePage extends StatelessWidget{
@override
Widget build(BuildContext context)=>SizedBox(child: Image.asset("home.jpg",fit: BoxFit.cover,),width: isWide ? MediaQuery.of(context).size.width-350 : MediaQuery.of(context).size.width,height: MediaQuery.of(context).size.height,);
}
在这里,我什至检查了"resolution of the device"。 isWide 布尔值为真,如果 MediaQuery.orientation == 风景。如果是这样,我在左侧有一个 350px 的菜单,所以我可以计算 sizedbox 的剩余 space。
希望这对您有所帮助!
从上面的解决方案开始,我想到了这个:
final Size size = _controller.value.size;
return Container(
color: Colors.lightBlue,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width,
child: FittedBox(
alignment: Alignment.center,
fit: BoxFit.fitWidth,
child: Container(
width: size.width,
height: size.height,
child: VideoPlayer(_controller))),
),
)
内部 Container
提供 VideoPlayer
内部 Texture
的大小。
我有一个 VideoPlayer 小部件,它需要全屏显示并且适合源视频的纵横比。为了实现这一点,我需要删除视频的 top/bottom 或 left/right。
我曾希望以下方法可以实现此目的,但我认为我一定是使用 FittedBox
不正确,因为它导致我的 VideoPlayer
消失:
final Size size = controller.value.size;
return new FittedBox(
fit: BoxFit.cover,
child: new AspectRatio(
aspectRatio: size.width / size.height,
child: new VideoPlayer(controller)
),
);
谁能帮我解决这个问题?
终于解决了。有一些缺失的部分:
- 我需要一个没有限制的
OverflowBox
,这样我的 child 就可以根据需要变大。 - 我需要
FittedBox
的 child 来实际强制执行大小以防止布局系统崩溃。 - 现在我的小部件将在其边界之外绘制,我们还想在其中放置一个
ClipRect
以阻止这种情况发生。
final Size size = controller.value.size;
return new ClipRect(
child: new OverflowBox(
maxWidth: double.infinity,
maxHeight: double.infinity,
alignment: Alignment.center,
child: new FittedBox(
fit: BoxFit.cover,
alignment: Alignment.center,
child: new Container(
width: size.width,
height: size.height,
child: new VideoPlayer(controller)
)
)
)
);
我遇到了很多问题,接受的答案并没有为我解决。我只是想让背景图像垂直放置并水平溢出。以下是我最终的做法:
OverflowBox(
maxWidth: double.infinity,
alignment: Alignment.center,
child:
Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
UnconstrainedBox(
constrainedAxis: Axis.vertical,
child: Image.asset('images/menu_photo_1.jpg', fit: BoxFit.cover))
])
)
我知道这个问题很老了,但我在这里 post 所以如果其他人找到它,他们会找到另一个解决方案。所以基本上,如果您总是想要一张图片覆盖一个区域,但又想始终显示图片的中间(我猜是中心裁剪),请在图片周围创建一个 sizedbox。您可能会说它没有响应或必须进行硬编码。只是从一些东西来计算它。我确实喜欢:
class HomePage extends StatelessWidget{
@override
Widget build(BuildContext context)=>SizedBox(child: Image.asset("home.jpg",fit: BoxFit.cover,),width: isWide ? MediaQuery.of(context).size.width-350 : MediaQuery.of(context).size.width,height: MediaQuery.of(context).size.height,);
}
在这里,我什至检查了"resolution of the device"。 isWide 布尔值为真,如果 MediaQuery.orientation == 风景。如果是这样,我在左侧有一个 350px 的菜单,所以我可以计算 sizedbox 的剩余 space。 希望这对您有所帮助!
从上面的解决方案开始,我想到了这个:
final Size size = _controller.value.size;
return Container(
color: Colors.lightBlue,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width,
child: FittedBox(
alignment: Alignment.center,
fit: BoxFit.fitWidth,
child: Container(
width: size.width,
height: size.height,
child: VideoPlayer(_controller))),
),
)
内部 Container
提供 VideoPlayer
内部 Texture
的大小。