效果图
修改位置
vendor\mediatek\proprietary\packages\apps\Dialer\java\com\android\incallui\video\impl\VideoCallFragment.java
直接注释掉 onCreateView() 中的 previewTextureView.setClipToOutline(true);这行代码,没错就是这么的简单粗暴就搞定了
public View onCreateView( LayoutInflater layoutInflater, @Nullable ViewGroup viewGroup, @Nullable Bundle bundle) { LogUtil.i("VideoCallFragment.onCreateView", null); ..... endCallButton.setOnClickListener(this); previewTextureView = (TextureView) view.findViewById(R.id.videocall_video_preview); //previewTextureView.setClipToOutline(true); previewOffOverlay.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { checkCameraPermission(); } }); ... }
为了美观,我们可以把矩形框以16:9的黄金比例缩放一下,并将我方预览矩形框移至右上角
vendor\mediatek\proprietary\packages\apps\Dialer\java\com\android\incallui\video\impl\res\layout\frag_videocall.xml
vendor\mediatek\proprietary\packages\apps\Dialer\java\com\android\incallui\video\impl\res\values\dimens.xml
<TextureView android:id="@+id/videocall_video_preview" android:layout_width="@dimen/videocall_preview_width" android:layout_height="@dimen/videocall_preview_height" android:layout_marginTop="@dimen/videocall_preview_margin_bottom" android:layout_marginEnd="@dimen/videocall_preview_margin_start" android:layout_alignParentRight="true" android:importantForAccessibility="no"/> <resources> <dimen name="videocall_preview_width">96dp</dimen> <dimen name="videocall_preview_height">118dp</dimen> </resources>
ok,这样就完成了产品经理的需求了。接下来,盘它,分析一下代码为啥注释掉这一行就能达到目标呢?
代码分析
先从UI入手,还是借用 工具找到对应的id videocall_video_preview,搜索发现有两处,
分别位于 frag_videocall.xml 和 frag_videocall_surfaceview.xml, 点进去确实发现里面对应的
videocall_video_preview 分别为 TextureView 和 SurfaceView,此处用到的是 TextureView,
在对应的 VideoCallFragment.java 中加载布局,可以看到dimens.xml中对应的宽高都为 72dp,那应该是一个正方形才对
由此猜想肯定是在 java 代码中进行了修改,带着疑问看到 VideoCallFragment 中
previewTextureView.setClipToOutline(true); previewTextureView.setOutlineProvider(circleOutlineProvider); private final ViewOutlineProvider circleOutlineProvider = new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { int x = view.getWidth() / 2; int y = view.getHeight() / 2; int radius = Math.min(x, y); outline.setOval(x - radius, y - radius, x + radius, y + radius); } };
以上代码是我精简组合后的关键代码,google工程师就是通过 setClipToOutline(true) 裁剪来实现圆角的,需要注意的是
setClipToOutline 和 setOutlineProvider 需要搭配使用,默认 ClipeToOutLine 是false的,这就是为什么注释了
previewTextureView.setClipToOutline(true) 就达到了我们的预期。
关于 setClipToOutline 相关的知识可看这篇