刷新SurfaceView之上的View时出错
当我想在表面视图之上显示普通视图对象时,我遇到了问题。 问题是: 如果我在布局xml文件中将普通视图的可见性设置为不可见,则视图的刷新不正确-视图和表面视图的重叠区域无法更新。 如果我在布局xml中将普通视图的可见性设置为可见,就没有问题。
这是我的测试代码:
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>
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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题解决了。
过程是:
要解决此问题,如果 SurfaceView 附加到窗口时小部件不可见,请在更改小部件的可见性时调用 requestTransparentRegion。
例如,您可以调用mWidget.getParent().requestTransparentRegion(mSurfaceView)。
由于ViewRoot是视图层次结构的根父级,因此调用SurfaceView的父级来请求透明区域具有相同的效果。
Problem solved.
the course is:
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.