当前位置: 首页 > article >正文

Android GLSurfaceView 覆盖其它控件问题 (RK平台)

在这里插入图片描述

平台

涉及主控: RK3566
Android: 11/13

问题

在使用GLSurfaceView播放视频的过程中, 增加了一个播放控制面板, 覆盖在视频上方. 默认隐藏setVisibility(View.INVISIBLE);点击屏幕再显示出来. 然而, 在RK3566上这个简单的功能却无法正常工作. 通过缩小视频窗口可以看到, 实际UI是已经展示, 但是被GLSurfaceView 覆盖了.

在Pixel Android 13 上不存在这个问题

在这里插入图片描述
如上图 红色 框选区域, 显示不出来.

分析

后续测试发现问题复现需要2个条件:

  1. 覆盖层默认布局设置了隐藏: android:visibility="invisible"
  2. 布局中使用了SurfaceView / GLSurfaceView

参考代码:

布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    android:id="@+id/rlRoot">
    <RelativeLayout android:id="@+id/rlScreen"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <RelativeLayout android:id="@+id/rlMenu"
        android:layout_width="480dp"
        android:layout_height="320dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="100dp"
        android:visibility="invisible"
        android:background="@drawable/selector_beauty_window_bg">
        <TextView
            android:text="Overlay Menu"
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </RelativeLayout>
</RelativeLayout>

Activity文件


import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.ansondroider.acore.BaseActivity;
import com.ansondroider.acore.media.VideoPlayer;
import com.ansondroider.apitester.gl.GLVideoView;

import java.io.IOException;

public class GlMenuOverlay extends BaseActivity {
    MediaPlayer mmp;
    GLVideoView glView;
    RelativeLayout rlScreen;
    RelativeLayout rlMenu;
    boolean playVideo = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_gl_menu_overlay);
        findViewById(R.id.rlRoot).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showOrHideMenu();
            }
        });
        rlScreen = (RelativeLayout) findViewById(R.id.rlScreen);
        rlMenu = (RelativeLayout) findViewById(R.id.rlMenu);

        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        if(playVideo) {
            glView = new GLVideoView(this);
            rlScreen.addView(glView, lp);
        }

        /*ImageView iv = new ImageView(this);
        iv.setImageResource(R.mipmap.ic_launcher);
        iv.setScaleType(ImageView.ScaleType.FIT_XY);
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        rlScreen.addView(iv, lp);*/

        VideoPlayer player = new VideoPlayer();
        SurfaceView texture = new SurfaceView(this);
        rlScreen.addView(texture, lp);
        player.setDisplay(texture);
        player.setDataSource("/sdcard/Movies/10012271.mp4");
        player.play();
    }

    void showOrHideMenu(){
        Log.d(TAG, "showOrHideMenu");
        rlMenu.setVisibility(rlMenu.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE);
    }

    @Override
    protected void onStart() {
        super.onStart();
        if(playVideo) {
            mmp = new MediaPlayer();
            try {
                mmp.setDataSource("/sdcard/Movies/10012271.mp4");
                mmp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mediaPlayer) {
                        glView.onVideoPrepared(mediaPlayer);
                    }
                });
                mmp.prepare();
                mmp.setLooping(true);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if(mmp != null){
            mmp.stop();
            mmp.release();
        }
    }
}

解决

在需要展示覆盖层的时候调用一次requestLayout, 比如:

    void showOrHideMenu(){
        Log.d(TAG, "showOrHideMenu");
        rlMenu.setVisibility(rlMenu.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE);
        //
        //((RelativeLayout)findViewById(R.id.rlRoot)).requestLayout();
        rlMenu.requestLayout();
    }

调用父容器 rlRootrlMenu本身requestLayout 都可以

在这里插入图片描述

参考

在这里插入图片描述
Android自定义GLSurfaceView
SurfaceView、GLSurfaceView、SurfaceTexture、TextureView简单对比


http://www.kler.cn/a/517663.html

相关文章:

  • 【BUUCTF】October 2019 Twice SQL Injection1及知识点整理
  • 微信小程序date picker的一些说明
  • 活动回顾和预告|微软开发者社区 Code Without Barriers 上海站首场活动成功举办!
  • 到华为考场考HCIE的注意事项和考试流程
  • 完全二叉树的节点个数(力扣222)
  • 【Java-数据结构】Java 链表面试题上 “最后一公里”:解决复杂链表问题的致胜法宝
  • 51单片机——定时器时钟
  • 微信小程序压缩图片
  • [目标检测] 如何快速验证pt在数据集(img, mp4)效果
  • 装饰器模式 - 装饰器模式的实现
  • Linux 消息队列的使用方法
  • 团体程序设计天梯赛-练习集——L1-016 查验身份证
  • java —— 面向对象(上)
  • [Dialog屏幕开发] 屏幕绘制(Table Control控件)
  • 为什么IDEA提示不推荐@Autowired❓️如果使用@Resource呢❓️
  • K8S中ingress详解
  • 数据结构测试题1
  • DeepSeek-R1:将强化学习用于激励大型语言模型的推理能力
  • 设计模式:春招面试的关键知识储备
  • ubunut22.04安装docker(基于阿里云 Docker 镜像源安装 Docker)
  • mapbox加载geojson,鼠标移入改变颜色,设置样式以及vue中的使用
  • web前端8--浮动
  • Python面向对象编程:精雕细琢对象的“名片”——重写 `__str__()` 和 `__repr__()` 方法
  • 【函数题】6-1 单链表逆转
  • 三高“高性能、高并发、高可靠”系统架构设计系列文章
  • 计算机视觉之三维重建-单视几何