public override bool onTouchEvent(android.view.MotionEvent @event) { if ((@event.getAction() == android.view.MotionEvent.ACTION_CANCEL) || (@event.getAction () == android.view.MotionEvent.ACTION_UP)) { mIsInLongpress = false; } return base.onTouchEvent(@event); }
public virtual bool onKeyOther(android.widget.TextView widget, android.text.Spannable text, android.view.KeyEvent @event) { int movementMetaState = getMovementMetaState(text, @event); int keyCode = @event.getKeyCode(); if (keyCode != android.view.KeyEvent.KEYCODE_UNKNOWN && @event.getAction() == android.view.KeyEvent .ACTION_MULTIPLE) { int repeat = @event.getRepeatCount(); bool handled = false; { for (int i = 0; i < repeat; i++) { if (!handleMovementKey(widget, text, keyCode, movementMetaState, @event)) { break; } handled = true; } } if (handled) { android.text.method.MetaKeyKeyListener.adjustMetaAfterKeypress(text); android.text.method.MetaKeyKeyListener.resetLockedMeta(text); } return handled; } return false; }
public override void onReceive(android.content.Context context, android.content.Intent intent) { // BEGIN_INCLUDE(onReceive) // Protect against rogue update broadcasts (not really a security issue, // just filter bad broacasts out so subclasses are less likely to crash). string action = intent.getAction(); if (android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE.Equals(action)) { android.os.Bundle extras = intent.getExtras(); if (extras != null) { int[] appWidgetIds = extras.getIntArray(android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS ); if (appWidgetIds != null && appWidgetIds.Length > 0) { this.onUpdate(context, android.appwidget.AppWidgetManager.getInstance(context), appWidgetIds ); } } } else { if (android.appwidget.AppWidgetManager.ACTION_APPWIDGET_DELETED.Equals(action)) { android.os.Bundle extras = intent.getExtras(); if (extras != null && extras.containsKey(android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID )) { int appWidgetId = extras.getInt(android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID ); this.onDeleted(context, new int[] { appWidgetId }); } } else { if (android.appwidget.AppWidgetManager.ACTION_APPWIDGET_ENABLED.Equals(action)) { this.onEnabled(context); } else { if (android.appwidget.AppWidgetManager.ACTION_APPWIDGET_DISABLED.Equals(action)) { this.onDisabled(context); } } } } }
public virtual bool onKey(android.content.DialogInterface dialog, int keyCode, android.view.KeyEvent @event) { if (keyCode == android.view.KeyEvent.KEYCODE_MENU || keyCode == android.view.KeyEvent .KEYCODE_BACK) { if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { android.view.Window win = mDialog.getWindow(); if (win != null) { android.view.View decor = win.getDecorView(); if (decor != null) { android.view.KeyEvent.DispatcherState ds = decor.getKeyDispatcherState(); if (ds != null) { ds.startTracking(@event, this); return true; } } } } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP && [email protected]()) { android.view.Window win = mDialog.getWindow(); if (win != null) { android.view.View decor = win.getDecorView(); if (decor != null) { android.view.KeyEvent.DispatcherState ds = decor.getKeyDispatcherState(); if (ds != null && ds.isTracking(@event)) { mMenu.close(true); dialog.dismiss(); return true; } } } } } } // Menu shortcut matching return mMenu.performShortcut(keyCode, @event, 0); }
public override void onReceive(android.content.Context context, android.content.Intent intent) { string action = intent.getAction(); if (android.content.Intent.ACTION_SCREEN_OFF.Equals(action)) { this._enclosing.mUserPresent = false; this._enclosing.updateRunning(); } else { if (android.content.Intent.ACTION_USER_PRESENT.Equals(action)) { this._enclosing.mUserPresent = true; this._enclosing.updateRunning(false); } } }
protected internal override bool handleMovementKey(android.widget.TextView widget , android.text.Spannable buffer, int keyCode, int movementMetaState, android.view.KeyEvent @event) { switch (keyCode) { case android.view.KeyEvent.KEYCODE_DPAD_CENTER: { if (android.view.KeyEvent.metaStateHasNoModifiers(movementMetaState)) { if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0 && android.text.method.MetaKeyKeyListener.getMetaState(buffer, android.text.method.MetaKeyKeyListener .META_SELECTING) != 0) { return widget.showContextMenu(); } } break; } } return base.handleMovementKey(widget, buffer, keyCode, movementMetaState, @event); }
private bool onContainerKey(android.view.KeyEvent @event) { int keyCode = @event.getKeyCode(); if (isInterestingKey(keyCode)) { if (keyCode == android.view.KeyEvent.KEYCODE_BACK) { if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { if (mOwnerView != null) { android.view.KeyEvent.DispatcherState ds = mOwnerView.getKeyDispatcherState(); if (ds != null) { ds.startTracking(@event, this); } } return true; } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP && @event.isTracking() && [email protected]()) { setVisible(false); return true; } } } else { dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT); } // Let the container handle the key return false; } else { android.view.ViewRootImpl viewRoot = getOwnerViewRootImpl(); if (viewRoot != null) { viewRoot.dispatchKey(@event); } // We gave the key to the owner, don't let the container handle this key return true; } }
/// <summary> /// Transforms a motion event into the coordinate space of a particular child view, /// filters out irrelevant pointer ids, and overrides its action if necessary. /// </summary> /// <remarks> /// Transforms a motion event into the coordinate space of a particular child view, /// filters out irrelevant pointer ids, and overrides its action if necessary. /// If child is null, assumes the MotionEvent will be sent to this ViewGroup instead. /// </remarks> private bool dispatchTransformedTouchEvent(android.view.MotionEvent @event, bool cancel, android.view.View child, int desiredPointerIdBits) { bool handled; // Canceling motions is a special case. We don't need to perform any transformations // or filtering. The important part is the action, not the contents. int oldAction = @event.getAction(); if (cancel || oldAction == android.view.MotionEvent.ACTION_CANCEL) { @event.setAction(android.view.MotionEvent.ACTION_CANCEL); if (child == null) { handled = base.dispatchTouchEvent(@event); } else { handled = child.dispatchTouchEvent(@event); } @event.setAction(oldAction); return handled; } // Calculate the number of pointers to deliver. int oldPointerIdBits = @event.getPointerIdBits(); int newPointerIdBits = oldPointerIdBits & desiredPointerIdBits; // If for some reason we ended up in an inconsistent state where it looks like we // might produce a motion event with no pointers in it, then drop the event. if (newPointerIdBits == 0) { return false; } // If the number of pointers is the same and we don't need to perform any fancy // irreversible transformations, then we can reuse the motion event for this // dispatch as long as we are careful to revert any changes we make. // Otherwise we need to make a copy. android.view.MotionEvent transformedEvent; if (newPointerIdBits == oldPointerIdBits) { if (child == null || child.hasIdentityMatrix()) { if (child == null) { handled = base.dispatchTouchEvent(@event); } else { float offsetX = mScrollX - child.mLeft; float offsetY = mScrollY - child.mTop; @event.offsetLocation(offsetX, offsetY); handled = child.dispatchTouchEvent(@event); @event.offsetLocation(-offsetX, -offsetY); } return handled; } transformedEvent = android.view.MotionEvent.obtain(@event); } else { transformedEvent = @event.split(newPointerIdBits); } // Perform any necessary transformations and dispatch. if (child == null) { handled = base.dispatchTouchEvent(transformedEvent); } else { float offsetX = mScrollX - child.mLeft; float offsetY = mScrollY - child.mTop; transformedEvent.offsetLocation(offsetX, offsetY); if (!child.hasIdentityMatrix()) { transformedEvent.transform(child.getInverseMatrix()); } handled = child.dispatchTouchEvent(transformedEvent); } // Done. transformedEvent.recycle(); return handled; }
public override void onReceive(android.content.Context context, android.content.Intent intent) { if (intent.getAction().Equals(android.content.Intent.ACTION_TIMEZONE_CHANGED)) { string tz = intent.getStringExtra("time-zone"); this._enclosing.mCalendar = new android.text.format.Time(java.util.TimeZone.getTimeZone (tz).getID()); } this._enclosing.onTimeChanged(); this._enclosing.invalidate(); }
public override bool onTouchEvent(android.view.MotionEvent @event) { if (!mIsUserSeekable || !isEnabled()) { return false; } switch (@event.getAction()) { case android.view.MotionEvent.ACTION_DOWN: { if (isInScrollingContainer()) { mTouchDownX = @event.getX(); } else { setPressed(true); if (mThumb != null) { invalidate(mThumb.getBounds()); } // This may be within the padding region onStartTrackingTouch(); trackTouchEvent(@event); attemptClaimDrag(); } break; } case android.view.MotionEvent.ACTION_MOVE: { if (mIsDragging) { trackTouchEvent(@event); } else { float x = @event.getX(); if (System.Math.Abs(x - mTouchDownX) > mScaledTouchSlop) { setPressed(true); if (mThumb != null) { invalidate(mThumb.getBounds()); } // This may be within the padding region onStartTrackingTouch(); trackTouchEvent(@event); attemptClaimDrag(); } } break; } case android.view.MotionEvent.ACTION_UP: { if (mIsDragging) { trackTouchEvent(@event); onStopTrackingTouch(); setPressed(false); } else { // Touch up when we never crossed the touch slop threshold should // be interpreted as a tap-seek to that location. onStartTrackingTouch(); trackTouchEvent(@event); onStopTrackingTouch(); } // ProgressBar doesn't know to repaint the thumb drawable // in its inactive state when the touch stops (because the // value has not apparently changed) invalidate(); break; } case android.view.MotionEvent.ACTION_CANCEL: { if (mIsDragging) { onStopTrackingTouch(); setPressed(false); } invalidate(); // see above explanation break; } } return true; }
public override bool dispatchKeyEvent(android.view.KeyEvent @event) { if (@event.getKeyCode() == android.view.KeyEvent.KEYCODE_BACK) { if (this.getKeyDispatcherState() == null) { return base.dispatchKeyEvent(@event); } if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { android.view.KeyEvent.DispatcherState state = this.getKeyDispatcherState(); if (state != null) { state.startTracking(@event, this); } return true; } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP) { android.view.KeyEvent.DispatcherState state = this.getKeyDispatcherState(); if (state != null && state.isTracking(@event) && [email protected]()) { this._enclosing.dismiss(); return true; } } } return base.dispatchKeyEvent(@event); } else { return base.dispatchKeyEvent(@event); } }
/// <summary>Filter pre-IME key events.</summary> /// <remarks> /// Filter pre-IME key events. By forwarding /// <see cref="android.view.View.onKeyPreIme(int, android.view.KeyEvent)">android.view.View.onKeyPreIme(int, android.view.KeyEvent) /// </see> /// events to this function, views using ListPopupWindow can have it dismiss the popup /// when the back key is pressed. /// </remarks> /// <param name="keyCode">keyCode param passed to the host view's onKeyPreIme</param> /// <param name="event">event param passed to the host view's onKeyPreIme</param> /// <returns>true if the event was handled, false if it was ignored.</returns> /// <seealso cref="setModal(bool)">setModal(bool)</seealso> public virtual bool onKeyPreIme(int keyCode, android.view.KeyEvent @event) { if (keyCode == android.view.KeyEvent.KEYCODE_BACK && isShowing()) { // special case for the back key, we do not even try to send it // to the drop down list but instead, consume it immediately android.view.View anchorView = mDropDownAnchorView; if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { android.view.KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); if (state != null) { state.startTracking(@event, this); } return true; } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP) { android.view.KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); if (state != null) { state.handleUpEvent(@event); } if (@event.isTracking() && [email protected]()) { dismiss(); return true; } } } } return false; }
/// <summary>React to the user typing while in the suggestions list.</summary> /// <remarks> /// React to the user typing while in the suggestions list. First, check for /// action keys. If not handled, try refocusing regular characters into the /// EditText. /// </remarks> private bool onSuggestionsKey(android.view.View v, int keyCode, android.view.KeyEvent @event) { // guard against possible race conditions (late arrival after dismiss) if (mSearchable == null) { return false; } if (mSuggestionsAdapter == null) { return false; } if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.hasNoModifiers ()) { // First, check for enter or search (both of which we'll treat as a // "click") if (keyCode == android.view.KeyEvent.KEYCODE_ENTER || keyCode == android.view.KeyEvent .KEYCODE_SEARCH || keyCode == android.view.KeyEvent.KEYCODE_TAB) { int position = mQueryTextView.getListSelection(); return onItemClicked(position, android.view.KeyEvent.KEYCODE_UNKNOWN, null); } // Next, check for left/right moves, which we use to "return" the // user to the edit view if (keyCode == android.view.KeyEvent.KEYCODE_DPAD_LEFT || keyCode == android.view.KeyEvent .KEYCODE_DPAD_RIGHT) { // give "focus" to text editor, with cursor at the beginning if // left key, at end if right key // TODO: Reverse left/right for right-to-left languages, e.g. // Arabic int selPoint = (keyCode == android.view.KeyEvent.KEYCODE_DPAD_LEFT) ? 0 : mQueryTextView .length(); mQueryTextView.setSelection(selPoint); mQueryTextView.setListSelection(0); mQueryTextView.clearListSelection(); mQueryTextView.ensureImeVisible(true); return true; } // Next, check for an "up and out" move if (keyCode == android.view.KeyEvent.KEYCODE_DPAD_UP && 0 == mQueryTextView.getListSelection ()) { // TODO: restoreUserQuery(); // let ACTV complete the move return false; } // Next, check for an "action key" android.app.SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode ); if ((actionKey != null) && ((actionKey.getSuggestActionMsg() != null) || (actionKey .getSuggestActionMsgColumn() != null))) { // launch suggestion using action key column int position = mQueryTextView.getListSelection(); if (position != android.widget.AdapterView.INVALID_POSITION) { android.database.Cursor c = mSuggestionsAdapter.getCursor(); if (c.moveToPosition(position)) { string actionMsg = getActionKeyMessage(c, actionKey); if (actionMsg != null && (actionMsg.Length > 0)) { return onItemClicked(position, keyCode, actionMsg); } } } } } return false; }
/// <summary>Checks a generic motion event.</summary> /// <remarks>Checks a generic motion event.</remarks> /// <param name="event">The event.</param> /// <param name="nestingLevel"> /// The nesting level: 0 if called from the base class, /// or 1 from a subclass. If the event was already checked by this consistency verifier /// at a higher nesting level, it will not be checked again. Used to handle the situation /// where a subclass dispatching method delegates to its superclass's dispatching method /// and both dispatching methods call into the consistency verifier. /// </param> public void onGenericMotionEvent(android.view.MotionEvent @event, int nestingLevel ) { if (!startEvent(@event, nestingLevel, EVENT_TYPE_GENERIC_MOTION)) { return; } try { ensureMetaStateIsNormalized(@event.getMetaState()); int action = @event.getAction(); int source = @event.getSource(); if ((source & android.view.InputDevice.SOURCE_CLASS_POINTER) != 0) { switch (action) { case android.view.MotionEvent.ACTION_HOVER_ENTER: { ensurePointerCountIsOneForThisAction(@event); mHoverEntered = true; break; } case android.view.MotionEvent.ACTION_HOVER_MOVE: { ensurePointerCountIsOneForThisAction(@event); break; } case android.view.MotionEvent.ACTION_HOVER_EXIT: { ensurePointerCountIsOneForThisAction(@event); if (!mHoverEntered) { problem("ACTION_HOVER_EXIT without prior ACTION_HOVER_ENTER"); } mHoverEntered = false; break; } case android.view.MotionEvent.ACTION_SCROLL: { ensureHistorySizeIsZeroForThisAction(@event); ensurePointerCountIsOneForThisAction(@event); break; } default: { problem("Invalid action for generic pointer event."); break; } } } else { if ((source & android.view.InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { switch (action) { case android.view.MotionEvent.ACTION_MOVE: { ensurePointerCountIsOneForThisAction(@event); break; } default: { problem("Invalid action for generic joystick event."); break; } } } } } finally { finishEvent(); } }
/// <summary>Checks a touch event.</summary> /// <remarks>Checks a touch event.</remarks> /// <param name="event">The event.</param> /// <param name="nestingLevel"> /// The nesting level: 0 if called from the base class, /// or 1 from a subclass. If the event was already checked by this consistency verifier /// at a higher nesting level, it will not be checked again. Used to handle the situation /// where a subclass dispatching method delegates to its superclass's dispatching method /// and both dispatching methods call into the consistency verifier. /// </param> public void onTouchEvent(android.view.MotionEvent @event, int nestingLevel) { if (!startEvent(@event, nestingLevel, EVENT_TYPE_TOUCH)) { return; } int action = @event.getAction(); bool newStream = action == android.view.MotionEvent.ACTION_DOWN || action == android.view.MotionEvent .ACTION_CANCEL; if (newStream && (mTouchEventStreamIsTainted || mTouchEventStreamUnhandled)) { mTouchEventStreamIsTainted = false; mTouchEventStreamUnhandled = false; mTouchEventStreamPointers = 0; } if (mTouchEventStreamIsTainted) { @event.setTainted(true); } try { ensureMetaStateIsNormalized(@event.getMetaState()); int deviceId = @event.getDeviceId(); int source = @event.getSource(); if (!newStream && mTouchEventStreamDeviceId != -1 && (mTouchEventStreamDeviceId != deviceId || mTouchEventStreamSource != source)) { problem("Touch event stream contains events from multiple sources: " + "previous device id " + mTouchEventStreamDeviceId + ", previous source " + Sharpen.Util.IntToHexString (mTouchEventStreamSource) + ", new device id " + deviceId + ", new source " + Sharpen.Util.IntToHexString (source)); } mTouchEventStreamDeviceId = deviceId; mTouchEventStreamSource = source; int pointerCount = @event.getPointerCount(); if ((source & android.view.InputDevice.SOURCE_CLASS_POINTER) != 0) { switch (action) { case android.view.MotionEvent.ACTION_DOWN: { if (mTouchEventStreamPointers != 0) { problem("ACTION_DOWN but pointers are already down. " + "Probably missing ACTION_UP from previous gesture." ); } ensureHistorySizeIsZeroForThisAction(@event); ensurePointerCountIsOneForThisAction(@event); mTouchEventStreamPointers = 1 << @event.getPointerId(0); break; } case android.view.MotionEvent.ACTION_UP: { ensureHistorySizeIsZeroForThisAction(@event); ensurePointerCountIsOneForThisAction(@event); mTouchEventStreamPointers = 0; mTouchEventStreamIsTainted = false; break; } case android.view.MotionEvent.ACTION_MOVE: { int expectedPointerCount = Sharpen.Util.IntGetBitCount(mTouchEventStreamPointers); if (pointerCount != expectedPointerCount) { problem("ACTION_MOVE contained " + pointerCount + " pointers but there are currently " + expectedPointerCount + " pointers down."); mTouchEventStreamIsTainted = true; } break; } case android.view.MotionEvent.ACTION_CANCEL: { mTouchEventStreamPointers = 0; mTouchEventStreamIsTainted = false; break; } case android.view.MotionEvent.ACTION_OUTSIDE: { if (mTouchEventStreamPointers != 0) { problem("ACTION_OUTSIDE but pointers are still down."); } ensureHistorySizeIsZeroForThisAction(@event); ensurePointerCountIsOneForThisAction(@event); mTouchEventStreamIsTainted = false; break; } default: { int actionMasked = @event.getActionMasked(); int actionIndex = @event.getActionIndex(); if (actionMasked == android.view.MotionEvent.ACTION_POINTER_DOWN) { if (mTouchEventStreamPointers == 0) { problem("ACTION_POINTER_DOWN but no other pointers were down."); mTouchEventStreamIsTainted = true; } if (actionIndex < 0 || actionIndex >= pointerCount) { problem("ACTION_POINTER_DOWN index is " + actionIndex + " but the pointer count is " + pointerCount + "."); mTouchEventStreamIsTainted = true; } else { int id = @event.getPointerId(actionIndex); int idBit = 1 << id; if ((mTouchEventStreamPointers & idBit) != 0) { problem("ACTION_POINTER_DOWN specified pointer id " + id + " which is already down." ); mTouchEventStreamIsTainted = true; } else { mTouchEventStreamPointers |= idBit; } } ensureHistorySizeIsZeroForThisAction(@event); } else { if (actionMasked == android.view.MotionEvent.ACTION_POINTER_UP) { if (actionIndex < 0 || actionIndex >= pointerCount) { problem("ACTION_POINTER_UP index is " + actionIndex + " but the pointer count is " + pointerCount + "."); mTouchEventStreamIsTainted = true; } else { int id = @event.getPointerId(actionIndex); int idBit = 1 << id; if ((mTouchEventStreamPointers & idBit) == 0) { problem("ACTION_POINTER_UP specified pointer id " + id + " which is not currently down." ); mTouchEventStreamIsTainted = true; } else { mTouchEventStreamPointers &= ~idBit; } } ensureHistorySizeIsZeroForThisAction(@event); } else { problem("Invalid action " + android.view.MotionEvent.actionToString(action) + " for touch event." ); } } break; } } } else { problem("Source was not SOURCE_CLASS_POINTER."); } } finally { finishEvent(); } }
/// <summary>Checks a trackball event.</summary> /// <remarks>Checks a trackball event.</remarks> /// <param name="event">The event.</param> /// <param name="nestingLevel"> /// The nesting level: 0 if called from the base class, /// or 1 from a subclass. If the event was already checked by this consistency verifier /// at a higher nesting level, it will not be checked again. Used to handle the situation /// where a subclass dispatching method delegates to its superclass's dispatching method /// and both dispatching methods call into the consistency verifier. /// </param> public void onTrackballEvent(android.view.MotionEvent @event, int nestingLevel) { if (!startEvent(@event, nestingLevel, EVENT_TYPE_TRACKBALL)) { return; } try { ensureMetaStateIsNormalized(@event.getMetaState()); int action = @event.getAction(); int source = @event.getSource(); if ((source & android.view.InputDevice.SOURCE_CLASS_TRACKBALL) != 0) { switch (action) { case android.view.MotionEvent.ACTION_DOWN: { if (mTrackballDown && !mTrackballUnhandled) { problem("ACTION_DOWN but trackball is already down."); } else { mTrackballDown = true; mTrackballUnhandled = false; } ensureHistorySizeIsZeroForThisAction(@event); ensurePointerCountIsOneForThisAction(@event); break; } case android.view.MotionEvent.ACTION_UP: { if (!mTrackballDown) { problem("ACTION_UP but trackball is not down."); } else { mTrackballDown = false; mTrackballUnhandled = false; } ensureHistorySizeIsZeroForThisAction(@event); ensurePointerCountIsOneForThisAction(@event); break; } case android.view.MotionEvent.ACTION_MOVE: { ensurePointerCountIsOneForThisAction(@event); break; } default: { problem("Invalid action " + android.view.MotionEvent.actionToString(action) + " for trackball event." ); break; } } if (mTrackballDown && @event.getPressure() <= 0) { problem("Trackball is down but pressure is not greater than 0."); } else { if (!mTrackballDown && @event.getPressure() != 0) { problem("Trackball is up but pressure is not equal to 0."); } } } else { problem("Source was not SOURCE_CLASS_TRACKBALL."); } } finally { finishEvent(); } }
/// <summary>Checks a key event.</summary> /// <remarks>Checks a key event.</remarks> /// <param name="event">The event.</param> /// <param name="nestingLevel"> /// The nesting level: 0 if called from the base class, /// or 1 from a subclass. If the event was already checked by this consistency verifier /// at a higher nesting level, it will not be checked again. Used to handle the situation /// where a subclass dispatching method delegates to its superclass's dispatching method /// and both dispatching methods call into the consistency verifier. /// </param> public void onKeyEvent(android.view.KeyEvent @event, int nestingLevel) { if (!startEvent(@event, nestingLevel, EVENT_TYPE_KEY)) { return; } try { ensureMetaStateIsNormalized(@event.getMetaState()); int action = @event.getAction(); int deviceId = @event.getDeviceId(); int source = @event.getSource(); int keyCode = @event.getKeyCode(); switch (action) { case android.view.KeyEvent.ACTION_DOWN: { android.view.InputEventConsistencyVerifier.KeyState state = findKeyState(deviceId , source, keyCode, false); if (state != null) { // If the key is already down, ensure it is a repeat. // We don't perform this check when processing raw device input // because the input dispatcher itself is responsible for setting // the key repeat count before it delivers input events. if (state.unhandled) { state.unhandled = false; } else { if ((mFlags & FLAG_RAW_DEVICE_INPUT) == 0 && @event.getRepeatCount() == 0) { problem("ACTION_DOWN but key is already down and this event " + "is not a key repeat." ); } } } else { addKeyState(deviceId, source, keyCode); } break; } case android.view.KeyEvent.ACTION_UP: { android.view.InputEventConsistencyVerifier.KeyState state = findKeyState(deviceId , source, keyCode, true); if (state == null) { problem("ACTION_UP but key was not down."); } else { state.recycle(); } break; } case android.view.KeyEvent.ACTION_MULTIPLE: { break; } default: { problem("Invalid action " + android.view.KeyEvent.actionToString(action) + " for key event." ); break; } } } finally { finishEvent(); } }
public override bool onTouchEvent(android.view.MotionEvent @event) { // Give everything to the gesture detector bool retValue = mGestureDetector.onTouchEvent(@event); int action = @event.getAction(); if (action == android.view.MotionEvent.ACTION_UP) { // Helper method for lifted finger onUp(); } else { if (action == android.view.MotionEvent.ACTION_CANCEL) { onCancel(); } } return retValue; }
public virtual bool dispatchTouchEvent(android.view.MotionEvent ev) { if (ev.getAction() == android.view.MotionEvent.ACTION_DOWN) { onUserInteraction(); } if (getWindow().superDispatchTouchEvent(ev)) { return true; } return onTouchEvent(ev); }
public virtual bool onTouch(android.view.View v, android.view.MotionEvent @event) { int action = @event.getAction(); if (@event.getPointerCount() > 1) { // ZoomButtonsController doesn't handle mutitouch. Give up control. return false; } if (mReleaseTouchListenerOnUp) { // The controls were dismissed but we need to throw away all events until the up if (action == android.view.MotionEvent.ACTION_UP || action == android.view.MotionEvent .ACTION_CANCEL) { mOwnerView.setOnTouchListener(null); setTouchTargetView(null); mReleaseTouchListenerOnUp = false; } // Eat this event return true; } dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT); android.view.View targetView = mTouchTargetView; switch (action) { case android.view.MotionEvent.ACTION_DOWN: { targetView = findViewForTouch((int)@event.getRawX(), (int)@event.getRawY()); setTouchTargetView(targetView); break; } case android.view.MotionEvent.ACTION_UP: case android.view.MotionEvent.ACTION_CANCEL: { setTouchTargetView(null); break; } } if (targetView != null) { // The upperleft corner of the target view in raw coordinates int targetViewRawX = mContainerRawLocation[0] + mTouchTargetWindowLocation[0]; int targetViewRawY = mContainerRawLocation[1] + mTouchTargetWindowLocation[1]; android.view.MotionEvent containerEvent = android.view.MotionEvent.obtain(@event); // Convert the motion event into the target view's coordinates (from // owner view's coordinates) containerEvent.offsetLocation(mOwnerViewRawLocation[0] - targetViewRawX, mOwnerViewRawLocation [1] - targetViewRawY); // These are floats because we need to potentially offset away this exact amount float containerX = containerEvent.getX(); float containerY = containerEvent.getY(); if (containerX < 0 && containerX > -ZOOM_CONTROLS_TOUCH_PADDING) { containerEvent.offsetLocation(-containerX, 0); } if (containerY < 0 && containerY > -ZOOM_CONTROLS_TOUCH_PADDING) { containerEvent.offsetLocation(0, -containerY); } bool retValue = targetView.dispatchTouchEvent(containerEvent); containerEvent.recycle(); return retValue; } else { return false; } }
public bool onKey(android.view.View v, int keyCode, android.view.KeyEvent @event) { // guard against possible race conditions if (this._enclosing.mSearchable == null) { return false; } // If a suggestion is selected, handle enter, search key, and action keys // as presses on the selected suggestion if (this._enclosing.mQueryTextView.isPopupShowing() && this._enclosing.mQueryTextView .getListSelection() != android.widget.AdapterView.INVALID_POSITION) { return this._enclosing.onSuggestionsKey(v, keyCode, @event); } // If there is text in the query box, handle enter, and action keys // The search key is handled by the dialog's onKeyDown(). if (!this._enclosing.mQueryTextView.isEmpty() && @event.hasNoModifiers()) { if (@event.getAction() == android.view.KeyEvent.ACTION_UP) { if (keyCode == android.view.KeyEvent.KEYCODE_ENTER) { v.cancelLongPress(); // Launch as a regular search. this._enclosing.launchQuerySearch(android.view.KeyEvent.KEYCODE_UNKNOWN, null, (( android.text.Editable)this._enclosing.mQueryTextView.getText()).ToString()); return true; } } if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN) { android.app.SearchableInfo.ActionKeyInfo actionKey = this._enclosing.mSearchable. findActionKey(keyCode); if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) { this._enclosing.launchQuerySearch(keyCode, actionKey.getQueryActionMsg(), ((android.text.Editable )this._enclosing.mQueryTextView.getText()).ToString()); return true; } } } return false; }
private void ensurePointerCountIsOneForThisAction(android.view.MotionEvent @event ) { int pointerCount = @event.getPointerCount(); if (pointerCount != 1) { problem("Pointer count is " + pointerCount + " but it should always be 1 for " + android.view.MotionEvent.actionToString(@event.getAction())); } }
public override bool onKeyPreIme(int keyCode, android.view.KeyEvent @event) { if (keyCode == android.view.KeyEvent.KEYCODE_BACK) { // special case for the back key, we do not even try to send it // to the drop down list but instead, consume it immediately if (@event.getAction() == android.view.KeyEvent.ACTION_DOWN && @event.getRepeatCount () == 0) { android.view.KeyEvent.DispatcherState state = getKeyDispatcherState(); if (state != null) { state.startTracking(@event, this); } return true; } else { if (@event.getAction() == android.view.KeyEvent.ACTION_UP) { android.view.KeyEvent.DispatcherState state = getKeyDispatcherState(); if (state != null) { state.handleUpEvent(@event); } if (@event.isTracking() && [email protected]()) { mSearchView.clearFocus(); mSearchView.setImeVisibility(false); return true; } } } } return base.onKeyPreIme(keyCode, @event); }
private void ensureHistorySizeIsZeroForThisAction(android.view.MotionEvent @event ) { int historySize = @event.getHistorySize(); if (historySize != 0) { problem("History size is " + historySize + " but it should always be 0 for " + android.view.MotionEvent .actionToString(@event.getAction())); } }
public virtual bool onTouch(android.view.View v, android.view.MotionEvent @event) { int action = @event.getAction(); int x = (int)@event.getX(); int y = (int)@event.getY(); if (action == android.view.MotionEvent.ACTION_DOWN && this._enclosing.mPopup != null && this._enclosing.mPopup.isShowing() && (x >= 0 && x < this._enclosing.mPopup. getWidth() && y >= 0 && y < this._enclosing.mPopup.getHeight())) { this._enclosing.mHandler.postDelayed(this._enclosing.mResizePopupRunnable, android.widget.ListPopupWindow .EXPAND_LIST_TIMEOUT); } else { if (action == android.view.MotionEvent.ACTION_UP) { this._enclosing.mHandler.removeCallbacks(this._enclosing.mResizePopupRunnable); } } return false; }
private void onSecondaryPointerUp(android.view.MotionEvent ev) { int pointerIndex = (ev.getAction() & android.view.MotionEvent.ACTION_POINTER_INDEX_MASK ) >> android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT; int pointerId = ev.getPointerId(pointerIndex); if (pointerId == mActivePointerId) { // This was our active pointer going up. Choose a new // active pointer and adjust accordingly. // TODO: Make this decision more intelligent. int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastMotionX = ev.getX(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); if (mVelocityTracker != null) { mVelocityTracker.clear(); } } }
public override bool onTouchEvent(android.view.MotionEvent @event) { int x = (int)@event.getX(); int y = (int)@event.getY(); if ((@event.getAction() == android.view.MotionEvent.ACTION_DOWN) && ((x < 0) || ( x >= this.getWidth()) || (y < 0) || (y >= this.getHeight()))) { this._enclosing.dismiss(); return true; } else { if (@event.getAction() == android.view.MotionEvent.ACTION_OUTSIDE) { this._enclosing.dismiss(); return true; } else { return base.onTouchEvent(@event); } } }
public override bool dispatchTouchEvent(android.view.MotionEvent ev) { if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onTouchEvent(ev, 1); } bool handled = false; if (onFilterTouchEventForSecurity(ev)) { int action = ev.getAction(); int actionMasked = action & android.view.MotionEvent.ACTION_MASK; // Handle an initial down. if (actionMasked == android.view.MotionEvent.ACTION_DOWN) { // Throw away all previous state when starting a new touch gesture. // The framework may have dropped the up or cancel event for the previous gesture // due to an app switch, ANR, or some other state change. cancelAndClearTouchTargets(ev); resetTouchState(); } // Check for interception. bool intercepted; if (actionMasked == android.view.MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { bool disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0; if (!disallowIntercept) { intercepted = onInterceptTouchEvent(ev); ev.setAction(action); } else { // restore action in case it was changed intercepted = false; } } else { // There are no touch targets and this action is not an initial down // so this view group continues to intercept touches. intercepted = true; } // Check for cancelation. bool canceled = resetCancelNextUpFlag(this) || actionMasked == android.view.MotionEvent .ACTION_CANCEL; // Update list of touch targets for pointer down, if needed. bool split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0; android.view.ViewGroup.TouchTarget newTouchTarget = null; bool alreadyDispatchedToNewTouchTarget = false; if (!canceled && !intercepted) { if (actionMasked == android.view.MotionEvent.ACTION_DOWN || (split && actionMasked == android.view.MotionEvent.ACTION_POINTER_DOWN) || actionMasked == android.view.MotionEvent .ACTION_HOVER_MOVE) { int actionIndex = ev.getActionIndex(); // always 0 for down int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex) : android.view.ViewGroup .TouchTarget.ALL_POINTER_IDS; // Clean up earlier touch targets for this pointer id in case they // have become out of sync. removePointersFromTouchTargets(idBitsToAssign); int childrenCount = mChildrenCount; if (childrenCount != 0) { // Find a child that can receive the event. // Scan children from front to back. android.view.View[] children = mChildren; float x = ev.getX(actionIndex); float y = ev.getY(actionIndex); { for (int i = childrenCount - 1; i >= 0; i--) { android.view.View child = children[i]; if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child , null)) { continue; } newTouchTarget = getTouchTarget(child); if (newTouchTarget != null) { // Child is already receiving touch within its bounds. // Give it the new pointer in addition to the ones it is handling. newTouchTarget.pointerIdBits |= idBitsToAssign; break; } resetCancelNextUpFlag(child); if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) { // Child wants to receive touch within its bounds. mLastTouchDownTime = ev.getDownTime(); mLastTouchDownIndex = i; mLastTouchDownX = ev.getX(); mLastTouchDownY = ev.getY(); newTouchTarget = addTouchTarget(child, idBitsToAssign); alreadyDispatchedToNewTouchTarget = true; break; } } } } if (newTouchTarget == null && mFirstTouchTarget != null) { // Did not find a child to receive the event. // Assign the pointer to the least recently added target. newTouchTarget = mFirstTouchTarget; while (newTouchTarget.next != null) { newTouchTarget = newTouchTarget.next; } newTouchTarget.pointerIdBits |= idBitsToAssign; } } } // Dispatch to touch targets. if (mFirstTouchTarget == null) { // No touch targets so treat this as an ordinary view. handled = dispatchTransformedTouchEvent(ev, canceled, null, android.view.ViewGroup .TouchTarget.ALL_POINTER_IDS); } else { // Dispatch to touch targets, excluding the new touch target if we already // dispatched to it. Cancel touch targets if necessary. android.view.ViewGroup.TouchTarget predecessor = null; android.view.ViewGroup.TouchTarget target = mFirstTouchTarget; while (target != null) { android.view.ViewGroup.TouchTarget next = target.next; if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) { handled = true; } else { bool cancelChild = resetCancelNextUpFlag(target.child) || intercepted; if (dispatchTransformedTouchEvent(ev, cancelChild, target.child, target.pointerIdBits )) { handled = true; } if (cancelChild) { if (predecessor == null) { mFirstTouchTarget = next; } else { predecessor.next = next; } target.recycle(); target = next; continue; } } predecessor = target; target = next; } } // Update list of touch targets for pointer up or cancel, if needed. if (canceled || actionMasked == android.view.MotionEvent.ACTION_UP || actionMasked == android.view.MotionEvent.ACTION_HOVER_MOVE) { resetTouchState(); } else { if (split && actionMasked == android.view.MotionEvent.ACTION_POINTER_UP) { int actionIndex = ev.getActionIndex(); int idBitsToRemove = 1 << ev.getPointerId(actionIndex); removePointersFromTouchTargets(idBitsToRemove); } } } if (!handled && mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onUnhandledEvent(ev, 1); } return handled; }
protected internal override bool dispatchHoverEvent(android.view.MotionEvent @event ) { int action = @event.getAction(); // First check whether the view group wants to intercept the hover event. bool interceptHover = onInterceptHoverEvent(@event); @event.setAction(action); // restore action in case it was changed android.view.MotionEvent eventNoHistory = @event; bool handled = false; // Send events to the hovered children and build a new list of hover targets until // one is found that handles the event. android.view.ViewGroup.HoverTarget firstOldHoverTarget = mFirstHoverTarget; mFirstHoverTarget = null; if (!interceptHover && action != android.view.MotionEvent.ACTION_HOVER_EXIT) { float x = @event.getX(); float y = @event.getY(); int childrenCount = mChildrenCount; if (childrenCount != 0) { android.view.View[] children = mChildren; android.view.ViewGroup.HoverTarget lastHoverTarget = null; { for (int i = childrenCount - 1; i >= 0; i--) { android.view.View child = children[i]; if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child , null)) { continue; } // Obtain a hover target for this child. Dequeue it from the // old hover target list if the child was previously hovered. android.view.ViewGroup.HoverTarget hoverTarget = firstOldHoverTarget; bool wasHovered; { for (android.view.ViewGroup.HoverTarget predecessor = null; ; ) { if (hoverTarget == null) { hoverTarget = android.view.ViewGroup.HoverTarget.obtain(child); wasHovered = false; break; } if (hoverTarget.child == child) { if (predecessor != null) { predecessor.next = hoverTarget.next; } else { firstOldHoverTarget = hoverTarget.next; } hoverTarget.next = null; wasHovered = true; break; } predecessor = hoverTarget; hoverTarget = hoverTarget.next; } } // Enqueue the hover target onto the new hover target list. if (lastHoverTarget != null) { lastHoverTarget.next = hoverTarget; } else { lastHoverTarget = hoverTarget; mFirstHoverTarget = hoverTarget; } // Dispatch the event to the child. if (action == android.view.MotionEvent.ACTION_HOVER_ENTER) { if (!wasHovered) { // Send the enter as is. handled |= dispatchTransformedGenericPointerEvent(@event, child); } } else { // enter if (action == android.view.MotionEvent.ACTION_HOVER_MOVE) { if (!wasHovered) { // Synthesize an enter from a move. eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory); eventNoHistory.setAction(android.view.MotionEvent.ACTION_HOVER_ENTER); handled |= dispatchTransformedGenericPointerEvent(eventNoHistory, child); // enter eventNoHistory.setAction(action); handled |= dispatchTransformedGenericPointerEvent(eventNoHistory, child); } else { // move // Send the move as is. handled |= dispatchTransformedGenericPointerEvent(@event, child); } } } if (handled) { break; } } } } } // Send exit events to all previously hovered children that are no longer hovered. while (firstOldHoverTarget != null) { android.view.View child = firstOldHoverTarget.child; // Exit the old hovered child. if (action == android.view.MotionEvent.ACTION_HOVER_EXIT) { // Send the exit as is. handled |= dispatchTransformedGenericPointerEvent(@event, child); } else { // exit // Synthesize an exit from a move or enter. // Ignore the result because hover focus has moved to a different view. if (action == android.view.MotionEvent.ACTION_HOVER_MOVE) { dispatchTransformedGenericPointerEvent(@event, child); } // move eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory); eventNoHistory.setAction(android.view.MotionEvent.ACTION_HOVER_EXIT); dispatchTransformedGenericPointerEvent(eventNoHistory, child); // exit eventNoHistory.setAction(action); } android.view.ViewGroup.HoverTarget nextOldHoverTarget = firstOldHoverTarget.next; firstOldHoverTarget.recycle(); firstOldHoverTarget = nextOldHoverTarget; } // Send events to the view group itself if no children have handled it. bool newHoveredSelf = !handled; if (newHoveredSelf == mHoveredSelf) { if (newHoveredSelf) { // Send event to the view group as before. handled |= base.dispatchHoverEvent(@event); } } else { if (mHoveredSelf) { // Exit the view group. if (action == android.view.MotionEvent.ACTION_HOVER_EXIT) { // Send the exit as is. handled |= base.dispatchHoverEvent(@event); } else { // exit // Synthesize an exit from a move or enter. // Ignore the result because hover focus is moving to a different view. if (action == android.view.MotionEvent.ACTION_HOVER_MOVE) { base.dispatchHoverEvent(@event); } // move eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory); eventNoHistory.setAction(android.view.MotionEvent.ACTION_HOVER_EXIT); base.dispatchHoverEvent(eventNoHistory); // exit eventNoHistory.setAction(action); } mHoveredSelf = false; } if (newHoveredSelf) { // Enter the view group. if (action == android.view.MotionEvent.ACTION_HOVER_ENTER) { // Send the enter as is. handled |= base.dispatchHoverEvent(@event); // enter mHoveredSelf = true; } else { if (action == android.view.MotionEvent.ACTION_HOVER_MOVE) { // Synthesize an enter from a move. eventNoHistory = obtainMotionEventNoHistoryOrSelf(eventNoHistory); eventNoHistory.setAction(android.view.MotionEvent.ACTION_HOVER_ENTER); handled |= base.dispatchHoverEvent(eventNoHistory); // enter eventNoHistory.setAction(action); handled |= base.dispatchHoverEvent(eventNoHistory); // move mHoveredSelf = true; } } } } // Recycle the copy of the event that we made. if (eventNoHistory != @event) { eventNoHistory.recycle(); } // Done. return handled; }
public override bool onGenericMotionEvent(android.view.MotionEvent @event) { if ((@event.getSource() & android.view.InputDevice.SOURCE_CLASS_POINTER) != 0) { switch (@event.getAction()) { case android.view.MotionEvent.ACTION_SCROLL: { if (!mIsBeingDragged) { float hscroll; if ((@event.getMetaState() & android.view.KeyEvent.META_SHIFT_ON) != 0) { hscroll = [email protected](android.view.MotionEvent.AXIS_VSCROLL); } else { hscroll = @event.getAxisValue(android.view.MotionEvent.AXIS_HSCROLL); } if (hscroll != 0) { int delta = (int)(hscroll * getHorizontalScrollFactor()); int range = getScrollRange(); int oldScrollX = mScrollX; int newScrollX = oldScrollX + delta; if (newScrollX < 0) { newScrollX = 0; } else { if (newScrollX > range) { newScrollX = range; } } if (newScrollX != oldScrollX) { base.scrollTo(newScrollX, mScrollY); return true; } } } break; } } } return base.onGenericMotionEvent(@event); }