在 SurfaceView 上刷新 View 时出错 [英] Error when refreshing View on top of SurfaceView

查看:22
本文介绍了在 SurfaceView 上刷新 View 时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我想在表面视图顶部显示普通视图对象时遇到了问题.问题是:如果我在layout xml文件中将普通视图的可见性设置为不可见,则视图的刷新不正确——视图和表面视图的重叠区域无法更新.如果我在layout xml中将普通视图的可见性设置为可见,就没有问题.

I met the problem when I want to display a normal view object on top a surfaceview. The problem is: If I set the visibility of the normal view to invisible in the layout xml file, the refreshing of the view is not correct - the overlapped area of view and surface view cannot be updated. If I set the visibility of the normal view to visible in the layout xml, there is no problem.

这是我的测试代码:

package com.test;

import java.io.IOException;


import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.widget.LinearLayout;


public class TESTActivity extends Activity implements Callback, OnPreparedListener {
    private SurfaceView mSurface1;
    private SurfaceHolder mSurfaceHolder1;
    private MediaPlayer mMediaPlayer1;
    private LinearLayout mLayout;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mLayout = (LinearLayout) findViewById(R.id.channel_subscribe);

        new Handler() {
            @Override
            public void handleMessage(Message m) {
                if(mLayout.getVisibility() == View.INVISIBLE)
                    mLayout.setVisibility(View.VISIBLE);
                else
                    mLayout.setVisibility(View.INVISIBLE);
                this.sendEmptyMessageDelayed(0, 4000);
            } 
        }.sendEmptyMessageDelayed(0, 4000);

        mSurface1 = (SurfaceView) findViewById(R.id.video_surface);
        mSurfaceHolder1 = mSurface1.getHolder();
        mSurfaceHolder1.addCallback(this);
        mSurfaceHolder1.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        mMediaPlayer1 = new MediaPlayer();
        mMediaPlayer1.setOnPreparedListener(this);

        try {
            mMediaPlayer1.setDataSource("/sdcard/d4.avi");
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.w("XXXXX", "Surface1 created");
        mMediaPlayer1.setDisplay(holder);
        mMediaPlayer1.prepareAsync();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        Log.w("XXXXX", "Mediaplayer prepared");
        mp.start();
    }
}

这是布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <SurfaceView android:id="@+id/video_surface"
        android:layout_width="480dip" 
        android:layout_height="270dip"
        android:layout_marginLeft="180dip"
        android:layout_marginTop="40dip"
        />
    <LinearLayout android:id="@+id/channel_subscribe" android:visibility="invisible" android:orientation="vertical" android:background="#bb161616" android:layout_width="436.0sp" android:layout_height="148.0sp" android:layout_alignParentBottom="true">
      <TextView android:textSize="14.0dip" android:textStyle="normal" android:textColor="#ffb7b7b7" android:id="@+id/subscribe_title" android:layout_width="wrap_content" android:layout_height="70.0sp" android:layout_marginLeft="38.0sp" android:layout_marginTop="18.0sp" android:layout_marginRight="34.0sp" android:text="We Hope you enjoyed the channel preview. To subscribe this channel, please press the button below." />
      <Button android:id="@+id/subscribe_now_button" android:layout_width="184.0sp" android:layout_height="42.0sp" android:layout_marginLeft="38.0sp" android:layout_marginRight="34.0sp" android:layout_marginBottom="18.0sp" android:text="SubscribeNow" />
     </LinearLayout>



</RelativeLayout>

推荐答案

问题已解决.

课程是:

  1. 在扩展活动布局期间,订阅对话框小部件被初始化为不可见.
  2. 然后将用于播放视频的 SurfaceView 附加到活动窗口.
  3. 当SurfaceView调用mParent.requestTransparentRegion(this)时;在回调 onAttachedToWindow() 中,对话框小部件不可见
  4. ViewRoot计算透明区域时,重叠区域被认为是不可见的,那么该区域的绘制是错误的.

要解决此问题,如果 SurfaceView 附加到窗口时不可见,请在更改小部件的可见性时调用 requestTransparentRegion.

To fix this issue, please call requestTransparentRegion when you change the visibility of the widget if it is not visible when SurfaceView is attached to window.

例如,您可以调用 mWidget.getParent().requestTransparentRegion(mSurfaceView).

For example, you can call mWidget.getParent().requestTransparentRegion(mSurfaceView).

由于ViewRoot是view hierachy的根父级,所以调用SurfaceView的父级请求transparentRegion的效果是一样的.

Since the ViewRoot is the root parent of the view hierachy, this will take the same effect to call SurfaceView’s parent to request transparentRegion.

这篇关于在 SurfaceView 上刷新 View 时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆