李華明Himi 原創,轉載務必在明顯處註明:
轉載自【黑米GameDev街區】 原文連結: http://www.himigame.com/android-game/315.html
很多童鞋說My Code運行後,點擊home或者back後會程式異常,如果你也這樣遇到過,那麼你肯定沒有仔細讀完Himi的博文,第十九篇Himi專門寫了關於這些錯誤的原因和解決方案,這裡我在部落格都補充說明下,省的童鞋們總疑惑這一塊;請點擊下面聯絡進入閱讀:
【Android遊戲開發十九】(必看篇)SurfaceView運行機制詳解—剖析Back與Home按鍵及切入後台等異常處理!
我們先講解在觸屏事件處理中我們需要改進的bug!然後再給出如何禁止橫屏和豎屏切換!以及切換的過程在android os 中是怎樣的。
先看一段代碼:
@Override<br />public boolean onTouchEvent(MotionEvent event) {<br />Log.v("test", "onTouchEvent");<br />bmp_y++;<br />if (event.getAction() == MotionEvent.ACTION_MOVE) {<br />Log.v("Himi", "ACTION_MOVE");<br />} else if (event.getAction() == MotionEvent.ACTION_DOWN) {<br />Log.v("Himi", "ACTION_DOWN");<br />} else if (event.getAction() == MotionEvent.ACTION_UP) {<br />Log.v("Himi", "ACTION_UP");<br />}<br />return true;<br />//return super.onTouchEvent(event);//備忘1<br />}<br />public boolean onKeyDown(int keyCode, KeyEvent event) {<br />Log.v("test", "onKeyDown");<br />bmp_x++;<br />return super.onKeyDown(keyCode, event);<br />}
代碼很簡單,一個是處理實體按鍵的回應時間,另一個是觸屏的響應事件、那麼這裡要說的有兩點:
第一點:
在surfaceview中我們的onKeyDown 雖然是重寫了view的函數,但是仍然需要在初始化的時候去聲明擷取焦點,setFocusable(true); 如果不調用此方法,那麼會造成按鍵無效。原因是因為如果是自己定義一個繼承自View的類,重新實現onKeyDown方法後,只有當該View獲得焦點時才會調用onKeyDown方法,Actvity中的onKeyDown方法是當所有控制項均沒有處理該按鍵事件時,才會調用.
第二點:
也是今天主要需要講得的觸屏響應的函數,onTouchEvent()! 重寫此函數的時候預設最後一句是依照基類的返回方式,return super.onTouchEvent(event); 然後我們在其中去判定 MotionEvent.ACTION_MOVE、MotionEvent.ACTION_DOWN、MotionEvent.ACTION_UP 相對應觸屏操作的 拖動、按下、抬起;對此一切都是正確的,但是真正的的運行起項目的時候發現 Log.v("Himi", "ACTION_MOVE"); 這裡log的"ACTION_MOVE",永遠不會執行!!!為此我找到瞭解決方法,那麼先解釋下為什麼會出現此類情況。
解釋:
onTouchEvent(),預設使用Oeverride這個方法,通常情況下去呼叫super.onTouchEvent()並傳回布林值。但是這裡要注意一點,預設如果去呼叫super.onTouchEvent()則很有可能super裡面並沒做任何事,並且回傳false回來,一旦回傳false回來,很可能後面的event (例如:Action_Move、Action_Up) 都會收不到了,所以為了確保保後面event能順利收到,要注意是否要直接呼super.TouchEvent()。
例如:
@Override<br />public boolean onTouchEvent(MotionEvent event) {<br />Log.i("ConanLog", "Event"+event.getAction());<br />return super.onTouchEvent(event);<br />}
這個例子是當你Touch Down的時候會送event進來,接著印出Log,然後呼叫super的onTouchEvent()並回傳布林值。此時會回傳false,並且之後再也收不到Touch Move或Touch Up的event,為了要確保能收到event,必須要回傳true,所以在這裡要注意一下。
這個問題也是當時用到此函數的時候發現的,找了很多資料才找到其解釋、所以以後使用onTouchEvent()函數的時候最後的
return super.onTouchEvent(event);
一定要改
return true;
最後還要注意一點:在初始化的時候不要忘記setFocusableInTouchMode(true);觸屏模式擷取焦點,比較類似 setFocusable(true);
——setFocusable(true);//此方法是用來響應按鍵!如果是自己定義一個繼承自View的類,重新實現onKeyDown方法後,只有當該View獲得焦點時才會調用onKeyDown方法,Actvity中的onKeyDown方法是當所有控制項均沒有處理該按鍵事件時,才會調用.
這裡講下如何禁止橫屏和豎屏切換!
在某些遊戲中我們可能需要禁止橫屏和豎屏切換,其實實現這個要求很簡單,只要在
AndroidManifest.xml 裡面加入這一行 android :screenOrientation="landscape "(landscape 是橫向,portrait 是縱向)。
在android中每次螢幕的切換動會重啟Activity,所以應該在Activity銷毀前儲存當前活動的狀態,在Activity再次Create的時候載入配置。在activity加上android:configChanges="keyboardHidden|orientation"屬性,就不會重啟activity.而是去調用onConfigurationChanged(Configuration newConfig). 這樣就可以在這個方法裡調整顯示方式.
MainActivity中:
public void onConfigurationChanged(Configuration newConfig) {<br />try {<br />super.onConfigurationChanged(newConfig);<br />if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {<br />Log.v("Himi", "onConfigurationChanged_ORIENTATION_LANDSCAPE");<br />} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {<br />Log.v("Himi", "onConfigurationChanged_ORIENTATION_PORTRAIT");<br />}<br />} catch (Exception ex) {<br />}<br />}
AndroidManifest.xml中:
<?xml version="1.0" encoding="utf-8"?><br /><manifest xmlns:android="http://schemas.android.com/apk/res/android"<br />package="com.himi" android:versionCode="1" android:versionName="1.0"><br /><application android:icon="@drawable/icon" android:label="@string/app_name"><br /><activity android:name=".MainActivity" android:label="@string/app_name"<br />android:screenOrientation="landscape" android:configChanges="keyboardHidden|orientation"><br /><intent-filter><br /><action android:name="android.intent.action.MAIN" /><br /><category android:name="android.intent.category.LAUNCHER" /><br /></intent-filter><br /></activity><br /></application><br /><uses-sdk android:minSdkVersion="4" /><br /></manifest>
(推薦大家訂閱本部落格,因為咱的更新速度可是很快的~娃哈哈)