错误的SurfaceView的顶部刷新查看时, [英] Error when refreshing View on top of SurfaceView

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

问题描述

我遇到的问题时,我希望显示在顶部surfaceview一个普通视图对象。 问题是: 如果我在布局XML文件中设置的普通视图的可见性,以无形的,视图的刷新是不正确的 - 的观点和表面观重叠区域不能被更新。 如果余设置的正常视图可见在布局的xml的可视性,是没有问题的。

下面是我的测试code:

  com.test包;

进口java.io.IOException异常;


进口android.app.Activity;
进口android.media.MediaPlayer;
进口android.media.MediaPlayer.On preparedListener;
进口android.os.Bundle;
进口android.os.Handler;
进口android.os.Message;
进口android.util.Log;
进口android.view.SurfaceHolder;
进口android.view.SurfaceHolder.Callback;
进口android.view.SurfaceView;
进口android.view.View;
进口android.widget.LinearLayout;


公共类TESTActivity扩展活动实现回调,在preparedListener {
    私人SurfaceView mSurface1;
    私人SurfaceHolder mSurfaceHolder1;
    私人MediaPlayer的mMediaPlayer1;
    私人的LinearLayout mLayout;

    / **第一次创建活动时调用。 * /
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);

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

        新的处理程序(){
            @覆盖
            公共无效的handleMessage(消息M){
                如果(mLayout.getVisibility()== View.INVISIBLE)
                    mLayout.setVisibility(View.VISIBLE);
                其他
                    mLayout.setVisibility(View.INVISIBLE);
                this.sendEmptyMessageDelayed(0,4000);
            }
        } .sendEmptyMessageDelayed(0,4000);

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

        mMediaPlayer1 =新的MediaPlayer();
        mMediaPlayer1.setOn preparedListener(本);

        尝试 {
            mMediaPlayer1.setDataSource(/ SD卡/ d4.avi);
        }赶上(抛出:IllegalArgumentException E){
            // TODO自动生成的catch块
            e.printStackTrace();
        }赶上(IllegalStateException异常E){
            // TODO自动生成的catch块
            e.printStackTrace();
        }赶上(IOException异常E){
            // TODO自动生成的catch块
            e.printStackTrace();
        }
    }

    @覆盖
    公共无效surfaceChanged(SurfaceHolder为arg0,诠释ARG1,诠释ARG2,诠释ARG3){
        // TODO自动生成方法存根

    }

    @覆盖
    公共无效surfaceCreated(SurfaceHolder持有者){
        Log.w(XXXXX,Surface1创建);
        mMediaPlayer1.setDisplay(保持器);
        。mMediaPlayer1 prepareAsync();

    }

    @覆盖
    公共无效surfaceDestroyed(SurfaceHolder为arg0){
        // TODO自动生成方法存根

    }

    @覆盖
    公共无效于prepared(MediaPlayer的MP){
        Log.w(XXXXX,媒体播放器prepared);
        mp.start();
    }
}
 

和这里的布局文件:

 < XML版本=1.0编码=UTF-8&GT?;
< RelativeLayout的机器人:layout_width =FILL_PARENT机器人:layout_height =FILL_PARENT
  的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android>
    < SurfaceView机器人:ID =@ + ID / video_surface
        机器人:layout_width =480dip
        机器人:layout_height =270dip
        机器人:layout_marginLeft =180dip
        机器人:layout_marginTop =40dip
        />
    <的LinearLayout机器人:ID =@ + ID / channel_subscribe机器人:知名度=隐形的Andr​​oid版本:方向=垂直机器人:后台=#bb161616机器人:layout_width =436.0sp机器人:layout_height =148.0 SP机器人:layout_alignParentBottom =真正的>
      < TextView的Andr​​oid版本:TEXTSIZE =14.0dip机器人:TEXTSTYLE =正常的Andr​​oid版本:文字颜色=#ffb7b7b7机器人:ID =@ + ID / subscribe_title机器人:layout_width =WRAP_CONTENT机器人:layout_height =70.0 SP机器人:layout_marginLeft =38.0sp机器人:layout_marginTop =18.0sp机器人:layout_marginRight =34.0sp。机器人:文本=我们希望你喜欢的频道preVIEW要订阅该频道,请preSS下面的按钮。 />
      <按钮机器人:ID =@ + ID / subscribe_now_button机器人:layout_width =184.0sp机器人:layout_height =42.0sp机器人:layout_marginLeft =38.0sp机器人:layout_marginRight =34.0sp机器人:layout_marginBottom = 18.0sp机器人:文本=SubscribeNow/>
     < / LinearLayout中>



< / RelativeLayout的>
 

解决方案

问题解决了。

当然是:

  1. 的订阅对话框窗口小部件膨胀活动布局过程中初始化为不可见。
  2. 然后用于附着到活动窗口播放视频的SurfaceView。
  3. 当SurfaceView调用mParent.requestTransparentRegion(本);在回调onAttachedToWindow(),对话框窗口小部件是无形
  4. 当的ViewRoot计算透明区域,所述重叠区域被认为是不可见的,然后该区域的画不正确。

要解决此问题,请致电requestTransparentRegion当您更改控件的可见性,如果它在SurfaceView连接到窗口是不可见的。

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

由于的ViewRoot认为层次结构的根母,这将花费同样的效果调用SurfaceView的父母要求transparentRegion。

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.

Here is my test code:

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();
    }
}

And here is the layout file:

<?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>

解决方案

Problem solved.

the course is:

  1. The subscribe dialog widget is initialized as invisible during inflating the activity layout.
  2. And then the SurfaceView used for playing video is attached to the activity window.
  3. When the SurfaceView invokes mParent.requestTransparentRegion(this); in the callback onAttachedToWindow(), the dialog widget is invisible
  4. When ViewRoot calculate the transparent region, the overlapped area is considered invisible, and then the painting of the area is incorrect.

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.

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

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的顶部刷新查看时,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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