如何在Flutter中进行“居中裁剪”Widget?

13

我有一个需要全屏并且适应源视频纵横比的VideoPlayer小部件。为了实现这一点,我需要剪切视频的上/下或左/右部分。

我本以为以下代码可以实现这一点,但我认为我可能错误地使用了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)
  ),
);

有人能帮我解决这个问题吗?


你尝试过使用ClipRect吗?https://docs.flutter.io/flutter/widgets/ClipRect-class.html - RedBrogdon
4个回答

34

最终解决了。有一些缺少的部分:

  1. 我需要一个没有限制的OverflowBox,让我的子组件可以尽可能地增大。
  2. 我需要使用FittedBox的子组件实际上强制指定大小,以防止布局系统崩溃。
  3. 现在,由于我的小部件将在其边界之外绘制,我们还希望在其中放置一个ClipRect来防止这种情况发生。
注意:翻译保留了原文中的HTML标签,但请注意在适当的环境下使用它们。
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)
      )
    )
  )
);

1
绝妙的解决方案。不使用包而直接解决了任何位置裁剪的问题。 - Vijay Kumar Kanta
有没有想法如何在任意偏移处进行裁剪? - csells

5
从上述解决方案入手,我得出了以下解决方案:
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))),
      ),
)

内部的容器VideoPlayer中的Texture提供大小。


1

我知道这个问题很旧,但我会在这里发布它,以便其他人找到它们可以找到另一种解决方案。所以基本上,如果你想让一张图片始终覆盖一个区域,但想始终显示图片的中间部分(我猜是中心裁剪),则在图像周围创建一个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,);
}

在这里,我甚至检查了“设备的分辨率”。如果MediaQuery.orientation == landscape,则isWide布尔值为true。如果是这样,我在左侧有一个350像素的菜单,因此我可以计算剩余的空间用于sizedbox。 希望这可以帮到你!


0

我在这方面遇到了很多问题,而且被接受的答案并没有解决我的问题。我只是想让背景图片在垂直方向上适应,并在水平方向上溢出。以下是我最终采用的方法:

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))
        ])
)

Image小部件没有内置的盒子适配功能吗?https://docs.flutter.io/flutter/widgets/Image-class.html - Bradley Campbell
它确实可以 - 正如您在我的代码中所看到的那样,我也在使用它。只是似乎没有完成工作。 - rjr-apps

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接