我有一個應用程序,我已經構建目標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獲取調用,此時兩者登錄statments成功完成。
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 statment:
mVideoView.startAnimation(flyOffAnim); //translate animation to "fly off" the screen.
我忘了之前提到的動畫。這可能與這種行爲有關嗎?
的flyOffAnimation有completionListener設置就可以了,只包含1點聲明:
mVideoView.setVisibility(View.GONE);
理論上這種行爲不應該改變。即使在ICS中,ViewGroup仍然會檢查每個孩子是否「能夠」接受觸摸,並且該能力是由其視圖掩碼只與「VISIBLE」相等來定義的,所以應該在父視圖中跳過「GONE」視圖'dispatchTouchEvent()'。我會試着開出一些時間來測試這個例子。 – Devunwired
它可能是設備特定的,但我只是在4.0.3模擬器中運行了一個簡單的例子,它的工作方式與預期的相同(偵聽器連接到'VideoView'在可見時觸及,然後在下面傳遞到下面的按鈕)它不是一個平臺問題。也許發佈一些代碼?也許你的觸摸監聽器中有些東西是橫向的? – Devunwired
我發現http://stackoverflow.com/a/7445557/247013是有用的和相關的。 –