diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 23cab4f..c6b9544 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -33,6 +33,7 @@ android:screenOrientation="portrait"/> + \ No newline at end of file diff --git a/res/layout/hover_emulator.xml b/res/layout/hover_emulator.xml new file mode 100644 index 0000000..365ece9 --- /dev/null +++ b/res/layout/hover_emulator.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/src/com/examples/customtouch/HoverEmulatorActivity.java b/src/com/examples/customtouch/HoverEmulatorActivity.java new file mode 100644 index 0000000..42ede5e --- /dev/null +++ b/src/com/examples/customtouch/HoverEmulatorActivity.java @@ -0,0 +1,45 @@ +package com.examples.customtouch; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; + +/** + * Created by Dave Smith + * Xcellent Creations, Inc. + * Date: 12/5/12 + * HoverEmulatorActivity + * Transform touch events into hover events + */ +public class HoverEmulatorActivity extends Activity implements View.OnHoverListener { + + public static final String TAG = "HoverEmulatorActivity"; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.hover_emulator); + + findViewById(R.id.button_hover).setOnHoverListener(this); + } + + @Override + public boolean onHover(View v, MotionEvent event) { + Log.i(TAG, "Hover Event "+getHoverName(event)); + return false; + } + + private String getHoverName(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_HOVER_ENTER: + return "HOVER_ENTER"; + case MotionEvent.ACTION_HOVER_MOVE: + return "HOVER_MOVE"; + case MotionEvent.ACTION_HOVER_EXIT: + return "HOVER_EXIT"; + default: + return ""; + } + } +} \ No newline at end of file diff --git a/src/com/examples/customtouch/HoverEmulatorButton.java b/src/com/examples/customtouch/HoverEmulatorButton.java new file mode 100644 index 0000000..54222db --- /dev/null +++ b/src/com/examples/customtouch/HoverEmulatorButton.java @@ -0,0 +1,99 @@ +package com.examples.customtouch; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.Button; + +/** + * Created by Dave Smith + * Xcellent Creations, Inc. + * Date: 12/5/12 + * HoverEmulatorButton + * Button that transforms single pointer events into hovers and multitouch events into taps + */ +public class HoverEmulatorButton extends Button { + + public HoverEmulatorButton(Context context) { + super(context); + } + + public HoverEmulatorButton(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public HoverEmulatorButton(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getPointerCount()) { + case 1: + handleSingleTouchEvent(event); + break; + default: + handleMultitouchEvent(event); + break; + } + + return true; + } + + private void handleSingleTouchEvent(MotionEvent event) { + switch(event.getAction()) { + case MotionEvent.ACTION_DOWN: + event.setAction(MotionEvent.ACTION_HOVER_ENTER); + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + event.setAction(MotionEvent.ACTION_HOVER_EXIT); + break; + case MotionEvent.ACTION_MOVE: + event.setAction(MotionEvent.ACTION_HOVER_MOVE); + break; + default: + //Ignore unknown events + return; + } + + //Forward the converted event to the proper callback + super.dispatchGenericMotionEvent(event); + } + + /* + * Forward all events with multiple fingers to super as if they were single pointer + * touch events + */ + private void handleMultitouchEvent(MotionEvent event) { + //Construct a new event that only contains a single pointer + MotionEvent newEvent = MotionEvent.obtain( + event.getDownTime(), + event.getEventTime(), + 0, + event.getX(), + event.getY(), + event.getMetaState() + ); + + switch (event.getActionMasked()) { + case MotionEvent.ACTION_POINTER_DOWN: + newEvent.setAction(MotionEvent.ACTION_DOWN); + break; + case MotionEvent.ACTION_POINTER_UP: + case MotionEvent.ACTION_CANCEL: + newEvent.setAction(MotionEvent.ACTION_UP); + break; + case MotionEvent.ACTION_MOVE: + //Leave this even unchanged + newEvent.setAction(MotionEvent.ACTION_MOVE); + break; + default: + //Ignore unknown events + return; + } + + //Forward the new event to super + super.onTouchEvent(newEvent); + } +} diff --git a/src/com/examples/customtouch/MainActivity.java b/src/com/examples/customtouch/MainActivity.java index 67d3333..6b54640 100644 --- a/src/com/examples/customtouch/MainActivity.java +++ b/src/com/examples/customtouch/MainActivity.java @@ -19,7 +19,7 @@ public class MainActivity extends ListActivity implements OnItemClickListener { "Pan Example", "Pan Gesture Example", "Multi-Touch Example", "Touch Forward Example", "Touch Delegate Example", "Touch Listener Example", - "Move Logger Example"}; + "Move Logger Example", "Hover Emulator"}; @Override protected void onCreate(Bundle savedInstanceState) { @@ -53,6 +53,9 @@ public void onItemClick(AdapterView parent, View view, int position, long id) case 6: //Move Logger View startActivity(new Intent(this, MoveLoggerActivity.class)); break; + case 7: //Hover emulator + startActivity(new Intent(this, HoverEmulatorActivity.class)); + break; default: break; }