我有一个我为SDK 3.0定制的应用程序。
在这个应用程序中,有一个相对布局,它有一个全屏VideoView,下面有一个按钮。视频视图上设置了onTouchListener,用于侦听手势。
视频完成后,VideoView
设置为visibility(View.GONE)
在运行Honeycomb(Toshiba Thrive和HTC Flyer)的设备上,此功能正如我所料。一旦VideoView
为GONE
,该按钮就可以点击了。
然而,在我运行ICS(摩托罗拉Xoom)的设备上,当我尝试按下该按钮时,事件将转到VideoView触控侦听器而不是按钮单击侦听器。
在这种情况下,意图的行为方式是否会在ICS上故意改变,或者这是一个错误?
此外,我试图解决这个问题的第一件事也给了我一些奇怪的结果。
我添加了这些行而不是setVisibility(View.GONE);
Log.i(MainActivity.myTag, "vid is null ? " + (mVideoView == null));
Log.i(MainActivity.myTag, "lyt is null ? " + (vidLyt == null));
vidLyt.removeView(mVideoView); //This line throws null pointer
认为如果VideoView
从我的父布局中删除,它肯定不再接受触摸事件。
但这会导致removeView()调用上出现空指针。尽管上面的Log语句表明两个对象实际上都不是null。这是一个例外:
据我所知,它实际上并没有指向我的活动中的任何一行,但是这3个语句是目前唯一被调用的3个语句,并且两个日志语句都成功完成。
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): java.lang.NullPointerException
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2488)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.View.getDisplayList(View.java:10415)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.View.getDisplayList(View.java:10380)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.View.getDisplayList(View.java:10380)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.View.getDisplayList(View.java:10380)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:840)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.ViewRootImpl.draw(ViewRootImpl.java:1910)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.os.Handler.dispatchMessage(Handler.java:99)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.os.Looper.loop(Looper.java:137)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at android.app.ActivityThread.main(ActivityThread.java:4424)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at java.lang.reflect.Method.invokeNative(Native Method)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at java.lang.reflect.Method.invoke(Method.java:511)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-20 16:32:42.480: ERROR/AndroidRuntime(9416): at dalvik.system.NativeStart.main(Native Method)
编辑:这是相关部分。
mVideoView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent me){
if(me.getAction() == MotionEvent.ACTION_DOWN){
touchY = me.getY();
//I am using the if statement below to fix the unexpected behavior currently.
//by returning false even though the VideoView receives the touch, this
//causes it to essentiall ignore it and pass it along to the button.
if(mVideoView.getVisibility() == View.GONE){
return false;
}
}else if(me.getAction() == MotionEvent.ACTION_UP){
Log.i(MainActivity.myTag, "Old = " + touchY + " New = " + me.getY());
//Moved north a little is the gesture I am interested in.
if(me.getY() < (touchY - 100)){
Thread t = new Thread() {
public void run(){
timeStamp = mVideoView.getCurrentPosition();
mVideoView.stopPlayback();
//Since we are in back thread use a handler to GONEify the VideoView
animVidHandler.sendEmptyMessage(0);
//There is some network stuff here that justifies the use of a
//different thread. But I am certain it isn't affecting the
//behavior of my views.
}
};
t.start();
}
}
return true;
}
});
处理程序回调中的只有1个语句:
mVideoView.startAnimation(flyOffAnim); //translate animation to "fly off" the screen.
我以前忘了提到动画。这可能与这种行为有关吗?
flyOffAnimation上设置了一个completionListener,它只包含1个语句:
mVideoView.setVisibility(View.GONE);
答案 0 :(得分:0)
在这种情况下,意图的行为方式是否会在ICS上故意改变,或者这是一个错误?
VideoView
真的是SurfaceView
,它实际上不是正常的View
,虽然它在电视上播放一个。
据我所知,它实际上并没有指向我活动中的任何一行,但这3个语句是目前唯一被调用的3个语句,两个日志语句都成功完成。
你没有从这三个陈述中得到NullPointerException
。你可能会在其他地方获得NullPointerException
作为这三个陈述的副作用。在这种情况下,我不知道你为什么会这样做。
也许尝试切换到ViewFlipper
中的同伴并在这种模式之间切换。