如何对同一布局内的VideoView与TextView完成完整截图
问题原因
VideoView底层基于SurfaceView实现,视频内容在独立的系统渲染图层绘制,不会存储到普通View的绘图缓存中,所以你用getDrawingCache的常规截图方式只能拿到TextView等普通控件的渲染结果,视频区域自然显示为黑色。
可行解决方案
方案1:替换VideoView为TextureView(推荐,改造成本最低)
TextureView的渲染内容会同步到View的绘图缓存,和普通View的截图逻辑完全兼容,不需要额外处理。
首先修改布局:
<RelativeLayout android:id="@+id/root_layout" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextureView android:id="@+id/video_player" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="SAMPLE" android:layout_centerInParent="true" /> </RelativeLayout>
后续视频播放逻辑和VideoView类似,只需要在TextureView的SurfaceTexture可用后绑定MediaPlayer即可,原有截图代码不需要任何修改就能直接拿到包含视频和文字的完整截图。
方案2:保留VideoView,手动合并视频帧和布局截图
如果你不想替换VideoView,可以分开抓取视频帧和布局内容后合成:
- 先获取VideoView的当前播放帧
- 再获取根布局除VideoView之外的截图
- 将两个Bitmap按位置叠加得到最终截图
参考代码如下:
public static Bitmap takeScreenshotWithVideo(RelativeLayout rootLayout, VideoView videoView) { // 1. 抓取视频当前帧 Bitmap videoFrame = videoView.getDrawingCache(); if (videoFrame == null) { videoFrame = Bitmap.createBitmap(videoView.getWidth(), videoView.getHeight(), Bitmap.Config.ARGB_8888); } // 2. 临时隐藏VideoView,抓其他控件的截图 videoView.setVisibility(View.INVISIBLE); rootLayout.setDrawingCacheEnabled(true); rootLayout.buildDrawingCache(true); Bitmap layoutBitmap = Bitmap.createBitmap(rootLayout.getDrawingCache()); rootLayout.setDrawingCacheEnabled(false); videoView.setVisibility(View.VISIBLE); // 3. 合并两个Bitmap Bitmap resultBitmap = Bitmap.createBitmap(rootLayout.getWidth(), rootLayout.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(resultBitmap); // 先画视频帧 canvas.drawBitmap(videoFrame, videoView.getLeft(), videoView.getTop(), null); // 再画布局其他内容(包含TextView) canvas.drawBitmap(layoutBitmap, 0, 0, null); // 回收临时Bitmap if (videoFrame != layoutBitmap) { videoFrame.recycle(); layoutBitmap.recycle(); } return resultBitmap; }
注意事项
- 截图操作需要在界面完全渲染完成后调用,避免拿到空白内容
- TextureView需要应用开启硬件加速才能正常工作,默认新建项目都是开启状态,不需要额外配置
内容的提问来源于stack exchange,提问作者Apptrends media
相关产品推荐
相关产品推荐

