[中文是轉的]
1、onInterceptTouchEvent()是用於處理事件(類似於預先處理,當然也可以不處理)並改變事件的傳遞方向,也就是決定是否允許Touch事件繼續向下(子控制項)傳遞,一但返回True(代表事件在當前的viewGroup中會被處理),則向下傳遞之路被截斷(所有子控制項將沒有機會參與Touch事件),同時把事件傳遞給當前的控制項的onTouchEvent()處理;返回false,則把事件交給子控制項的onInterceptTouchEvent()
2、onTouchEvent()用於處理事件,傳回值決定當前控制項是否消費(consume)了這個事件,也就是說在當前控制項在處理完Touch事件後,是否還允許Touch事件繼續向上(父控制項)傳遞,一但返回True,則父控制項不用操心自己來處理Touch事件。返回true,則向上傳遞給父控制項(註:可能你會覺得是否消費了有關係嗎,反正我已經針對事件編寫了處理代碼?答案是有區別!比如ACTION_MOVE或者ACTION_UP發生的前提是一定曾經發生了ACTION_DOWN,如果你沒有消費ACTION_DOWN,那麼系統會認為ACTION_DOWN沒有發生過,所以ACTION_MOVE或者ACTION_UP就不能被捕獲。)
final int viewId = view.getId(); final int action = event.getActionMasked() & MotionEvent.ACTION_MASK; final int actionIndex = event.getActionIndex();switch (action) { case MotionEvent.ACTION_UP: // 這裡的view有錯誤:假如先按住方向不松,再按子彈不松; // 接著鬆開方向;最後鬆開子彈;那麼,子彈按鈕將不會得到釋放 view.setPressed(false); m_offsetX = m_offsetY = 0; int x = (int)event.getRawX(), y = (int)event.getRawY(); if (m_fireRect.contains(x, y)) { if (R.id.fire != viewId) findViewById(R.id.fire).setPressed(false); } else if (m_padRect.contains(x, y)) { if (R.id.pad != viewId) findViewById(R.id.pad).setPressed(false); // 做關於雪地的滑行 int gridx = pMe.GetGrid().x; int gridy = pMe.GetGrid().y; if (GameWorld.SNOW == GameWorld.Instance().GetTerrain(gridx, gridy, GameWorld.TERRAIN_TYPE_ALL) || GameWorld.SNOW == GameWorld.Instance().GetTerrain(gridx + 1, gridy + 1, GameWorld.TERRAIN_TYPE_ALL) ) { pMe.Slide(); } else { pMe.SetDir(Dir.NONE); } } break; case MotionEvent.ACTION_MOVE: // 先調整事件的座標相對原點 event.offsetLocation(m_offsetX, m_offsetY); //Log.d(TAG, "DOWN X " + event.getX(actionIndex) + " Y " + event.getY(actionIndex)); ButtonType type = GetButton(event.getX(actionIndex), event.getY(actionIndex)); switch (type) { case UP: case DOWN: case LEFT: case RIGHT: DoMove(type); break; case FIRE: if (pMe.Fire()) { AudioPool.Play(m_soundId[AudioID.AUDIO_FIRE.ordinal()], GetCurVolume(), 0); } break; default: pMe.SetDir(Dir.NONE); break; } break; case MotionEvent.ACTION_DOWN: //Log.d(TAG, "First ( " + m_offsetX + " , " + m_offsetY + " )"); view.setPressed(true); switch (viewId) { case R.id.fire: m_offsetX = m_fireRect.left; m_offsetY = m_fireRect.top; if (pMe.Fire()) { AudioPool.Play(m_soundId[AudioID.AUDIO_FIRE.ordinal()], GetCurVolume(), 0); } break; case R.id.pad: m_offsetX = m_padRect.left; m_offsetY = m_padRect.top; type = GetButton(event.getRawX(), event.getRawY()); switch (type) { case UP: case DOWN: case LEFT: case RIGHT: pMe.StopSlide(); DoMove(type); break; default: pMe.SetDir(Dir.NONE); break; } default: break; } break; case MotionEvent.ACTION_POINTER_DOWN: // 先調整事件的座標相對原點 event.offsetLocation(m_offsetX, m_offsetY); Log.d(TAG, "ACTION_POINTER_DOWN X " + event.getX(actionIndex) + " Y " + event.getY(actionIndex)); type = GetButton(event.getX(actionIndex), event.getY(actionIndex)); switch (type) { case UP: case DOWN: case LEFT: case RIGHT: findViewById(R.id.pad).setPressed(true); DoMove(type); break; case FIRE: findViewById(R.id.fire).setPressed(true); if (pMe.Fire()) { AudioPool.Play(m_soundId[AudioID.AUDIO_FIRE.ordinal()], GetCurVolume(), 0); } break; default: break; } break; case MotionEvent.ACTION_POINTER_UP: // 先調整事件的座標相對原點 event.offsetLocation(m_offsetX, m_offsetY); Log.d(TAG, "ACTION_POINTER_UP X " + event.getX(actionIndex) + " Y " + event.getY(actionIndex)); type = GetButton(event.getX(actionIndex), event.getY(actionIndex)); switch (type) { case UP: case DOWN: case LEFT: case RIGHT: findViewById(R.id.pad).setPressed(false); pMe.SetDir(Dir.NONE); break; case FIRE: findViewById(R.id.fire).setPressed(false); break; default: findViewById(R.id.pad).setPressed(false); findViewById(R.id.fire).setPressed(false); pMe.SetDir(Dir.NONE); break; } break; default: // FOR OTHER EVENTS break;}