List of usage examples for android.view ScaleGestureDetector onTouchEvent
public boolean onTouchEvent(MotionEvent event)
From source file:com.gmail.walles.johan.batterylogger.BatteryPlotFragment.java
private View.OnTouchListener getOnTouchListener(final XYPlot plot) { final GestureDetector gestureDetector = getOneFingerGestureDetector(plot); final ScaleGestureDetector scaleGestureDetector = getTwoFingerGestureDetector(plot); return new View.OnTouchListener() { @Override//from w ww .j a va 2 s. c om public boolean onTouch(View view, MotionEvent motionEvent) { boolean returnMe; returnMe = scaleGestureDetector.onTouchEvent(motionEvent); returnMe |= gestureDetector.onTouchEvent(motionEvent); returnMe |= view.onTouchEvent(motionEvent); return returnMe; } }; }
From source file:com.example.zayankovsky.homework.ui.ImageDetailActivity.java
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.image_detail); getWindow().getDecorView().setBackgroundResource( PreferenceManager.getDefaultSharedPreferences(this).getString("theme", "light").equals("dark") ? R.color.darkColorTransparent : R.color.lightColorTransparent); // Set up activity to go full screen getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN); // Locate the main ImageView and TextView mImageView = (ImageView) findViewById(R.id.imageView); final TextView mTextView = (TextView) findViewById(R.id.textView); mSectionNumber = getIntent().getIntExtra(SECTION_NUMBER, 0); registerForContextMenu(mImageView);/*www.j a v a 2 s . c o m*/ mImageView.setLongClickable(false); // Enable some additional newer visibility and ActionBar features // to create a more immersive photo viewing experience final ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { // Set home as up actionBar.setDisplayHomeAsUpEnabled(true); // Hide and show the ActionBar and TextView as the visibility changes mImageView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { @Override public void onSystemUiVisibilityChange(int vis) { if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { actionBar.hide(); if (mSectionNumber == 1) { mTextView.animate().translationY(mTextView.getHeight()) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mTextView.setVisibility(View.GONE); } }); } } else { actionBar.show(); if (mSectionNumber == 1) { mTextView.animate().translationY(0).setListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { mTextView.setVisibility(View.VISIBLE); } }); } } } }); // Start low profile mode and hide ActionBar mImageView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); actionBar.hide(); } GestureListener.init(this, mImageView); ScaleGestureListener.init(mImageView); // Use the ImageWorker to load the image into the ImageView // (so a single cache can be used over all pages in the ViewPager) // based on the extra passed in to this activity int position = getIntent().getIntExtra(POSITION, 0); switch (mSectionNumber) { case 0: GalleryWorker.loadImage(position, mImageView); break; case 1: FotkiWorker.loadImage(position, mImageView); mTextView.setText(getResources().getString(R.string.detail_text, FotkiWorker.getAuthor(), new SimpleDateFormat("d MMMM yyyy", Locale.getDefault()).format(FotkiWorker.getPublished()))); break; case 2: ResourcesWorker.loadImage(position, mImageView); break; } setTitle(ImageWorker.getTitle()); // First we create the GestureListener that will include all our callbacks. // Then we create the GestureDetector, which takes that listener as an argument. GestureDetector.SimpleOnGestureListener gestureListener = new GestureListener(); final GestureDetector gd = new GestureDetector(this, gestureListener); ScaleGestureDetector.SimpleOnScaleGestureListener scaleGestureListener = new ScaleGestureListener(); final ScaleGestureDetector sgd = new ScaleGestureDetector(this, scaleGestureListener); /* For the view where gestures will occur, we create an onTouchListener that sends * all motion events to the gesture detectors. When the gesture detectors * actually detects an event, it will use the callbacks we created in the * SimpleOnGestureListener and SimpleOnScaleGestureListener to alert our application. */ findViewById(R.id.frameLayout).setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { gd.onTouchEvent(motionEvent); sgd.onTouchEvent(motionEvent); return true; } }); }
From source file:org.protocoderrunner.apprunner.api.PUI.java
@ProtocoderScript @APIMethod(description = "Starts a gesture detector over a view", example = "") @APIParam(params = { "View", "function(data)" }) //http://stackoverflow.com/questions/6599329/can-one-ongesturelistener-object-deal-with-two-gesturedetector-objects public void gestureDetector(View v, final addGestureDetectorCB cb) { final GestureDetectorReturn g = new GestureDetectorReturn(); final GestureDetector gestureDetector = new GestureDetector(a.get(), new GestureDetector.OnGestureListener() { @Override/*from w ww . j ava 2s .com*/ public boolean onSingleTapUp(MotionEvent e) { g.type = "up"; cb.event(g); return false; } @Override public void onShowPress(MotionEvent e) { g.type = "showpress"; cb.event(g); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { g.type = "scroll"; g.data = new JSONObject(); try { g.data.put("distanceX", distanceX); g.data.put("distanceY", distanceY); } catch (JSONException e) { e.printStackTrace(); } cb.event(g); return true; } @Override public void onLongPress(MotionEvent e) { g.type = "longpress"; cb.event(g); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { g.type = "fling"; g.data = new JSONObject(); try { g.data.put("velocityX", velocityX); g.data.put("velocityY", velocityY); } catch (JSONException e) { e.printStackTrace(); } cb.event(g); return true; } @Override public boolean onDown(MotionEvent e) { g.type = "down"; cb.event(g); return true; } }); final ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(a.get(), new OnScaleGestureListener() { @Override public boolean onScale(ScaleGestureDetector scaleGestureDetector) { g.type = "scale"; cb.event(g); return false; } @Override public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) { g.type = "scaleBegin"; cb.event(g); return false; } @Override public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) { g.type = "scaleEnd"; cb.event(g); } }); v.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { scaleGestureDetector.onTouchEvent(event); if (scaleGestureDetector.isInProgress()) return true; gestureDetector.onTouchEvent(event); return true; } }); }
From source file:pl.edu.agh.mindmapex.gui.MainActivity.java
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); progressDialog = ProgressDialog.show(this, "Drawing", "Please wait...", true, false); if (WelcomeScreen.workbook != null) { workbook = WelcomeScreen.workbook; }// w w w . j a va 2 s . c o m res = getResources(); if (handler == null) { handler = WorkbookHandler.createNewWorkbook(); } if (workbook == null) { workbook = handler.getWorkbook(); styleSheet = workbook.getStyleSheet(); style1 = styleSheet.createStyle(IStyle.TOPIC); styleSheet.addStyle(style1, IStyleSheet.NORMAL_STYLES); } styleSheet = workbook.getStyleSheet(); sheet1 = workbook.getPrimarySheet(); res = getResources(); if (style == null) { Intent intent = getIntent(); style = intent.getStringExtra(WelcomeScreen.STYLE); } if (root == null) { // Display display = getWindowManager().getDefaultDisplay(); setContentView(R.layout.main_content_view); lay = (DrawView) findViewById(R.id.main_draw_view); lay.post(new Runnable() { @Override public void run() { rootTopic = sheet1.getRootTopic(); root = new Box(); // Point size = new Point(lay.getWidth(), lay.getHeight()); // width = size.x / 2; // height = size.y / 2; root.setPoint(new pl.edu.agh.mindmapex.common.Point( lay.getWidth() / 2 - getResources().getDimensionPixelSize(R.dimen.init_box_size), lay.getHeight() / 2 - getResources().getDimensionPixelSize(R.dimen.init_box_size_height))); lay.setZOrderOnTop(true); if (style.equals("ReadyMap")) { if (sheet1.getTheme() == null) { root.setPoint(new pl.edu.agh.mindmapex.common.Point(width, height)); final HashMap<String, Box> boxes = new HashMap<>(); root.topic = rootTopic; if (root.topic.getStyleId() != null) { checkStyle(root); } else { root.setDrawableShape(res.getDrawable(R.drawable.round_rect)); } root.topic.setFolded(false); boxes.put(root.topic.getId(), root); for (ITopic t : root.topic.getAllChildren()) { Box b = new Box(); b.topic = t; boxes.put(root.topic.getId(), root); b.point = new pl.edu.agh.mindmapex.common.Point(); if (b.topic.getStyleId() != null) { checkStyle(b); } else { b.setDrawableShape(res.getDrawable(R.drawable.round_rect)); } b.parent = root; root.addChild(b); rootTopic.add(b.topic, 0, ITopic.ATTACHED); Utils.fireAddSubtopic(b, boxes); boxes.put(t.getId(), b); } Utils.findRelationships(boxes); } else { if (sheet1.getTheme().getName().equals("%classic") || sheet1.getTheme().getName().equals("%comic")) { root.setPoint(new pl.edu.agh.mindmapex.common.Point(width, height)); root.topic = rootTopic; final HashMap<String, Box> boxes = new HashMap<>(); if (root.topic.getStyleId() != null) { checkStyle(root); } else { root.setDrawableShape(res.getDrawable(R.drawable.elipse)); } root.topic.setFolded(false); boxes.put(root.topic.getId(), root); for (ITopic t : root.topic.getAllChildren()) { Box b = new Box(); b.topic = t; b.point = new pl.edu.agh.mindmapex.common.Point(); boxes.put(root.topic.getId(), root); if (b.topic.getStyleId() != null) { checkStyle(b); } else { b.setDrawableShape(res.getDrawable(R.drawable.round_rect)); } b.parent = root; root.addChild(b); Utils.fireAddSubtopic(b, boxes); rootTopic.add(b.topic, 0, ITopic.ATTACHED); boxes.put(t.getId(), b); } Utils.findRelationships(boxes); } else if (sheet1.getTheme().getName().equals("%simple")) { root.setPoint(new pl.edu.agh.mindmapex.common.Point(width, height)); final HashMap<String, Box> boxes = new HashMap<>(); root.topic = rootTopic; if (root.topic.getStyleId() != null) { checkStyle(root); } else { root.setDrawableShape(res.getDrawable(R.drawable.elipse)); } root.topic.setFolded(false); boxes.put(root.topic.getId(), root); for (ITopic t : root.topic.getAllChildren()) { Box b = new Box(); b.topic = t; b.point = new pl.edu.agh.mindmapex.common.Point(); boxes.put(root.topic.getId(), root); if (b.topic.getStyleId() != null) { checkStyle(b); } else { b.setDrawableShape(res.getDrawable(R.drawable.no_border)); } b.parent = root; root.addChild(b); rootTopic.add(b.topic, 0, ITopic.ATTACHED); Utils.fireAddSubtopic(b, boxes); boxes.put(t.getId(), b); } Utils.findRelationships(boxes); } else if (sheet1.getTheme().getName().equals("%bussiness")) { root.setPoint(new pl.edu.agh.mindmapex.common.Point(width, height)); final HashMap<String, Box> boxes = new HashMap<>(); root.topic = rootTopic; if (root.topic.getStyleId() != null) { checkStyle(root); } else { root.setDrawableShape(res.getDrawable(R.drawable.round_rect)); } root.topic.setFolded(false); boxes.put(root.topic.getId(), root); for (ITopic t : root.topic.getAllChildren()) { Box b = new Box(); b.topic = t; b.point = new pl.edu.agh.mindmapex.common.Point(); boxes.put(root.topic.getId(), root); if (b.topic.getStyleId() != null) { checkStyle(b); } else { b.setDrawableShape(res.getDrawable(R.drawable.rect)); } b.parent = root; root.addChild(b); rootTopic.add(b.topic, 0, ITopic.ATTACHED); Utils.fireAddSubtopic(b, boxes); boxes.put(t.getId(), b); } Utils.findRelationships(boxes); } else if (sheet1.getTheme().getName().equals("%academese")) { root.setPoint(new pl.edu.agh.mindmapex.common.Point(width, height)); final HashMap<String, Box> boxes = new HashMap<>(); root.topic = rootTopic; if (root.topic.getStyleId() != null) { checkStyle(root); } else { root.setDrawableShape(res.getDrawable(R.drawable.rect)); } root.topic.setFolded(false); Style s = (Style) workbook.getStyleSheet().createStyle(IStyle.MAP); s.setProperty(Styles.FillColor, Integer.toString(res.getColor(R.color.dark_gray), 16)); styleSheet.addStyle(s, IStyleSheet.NORMAL_STYLES); sheet1.setStyleId(s.getId()); lay.setBackgroundColor(res.getColor(R.color.dark_gray)); boxes.put(root.topic.getId(), root); for (ITopic t : root.topic.getAllChildren()) { Box b = new Box(); b.topic = t; b.point = new pl.edu.agh.mindmapex.common.Point(); boxes.put(root.topic.getId(), root); if (b.topic.getStyleId() != null) { checkStyle(b); } else { b.setDrawableShape(res.getDrawable(R.drawable.elipse)); } b.parent = root; root.addChild(b); Utils.fireAddSubtopic(b, boxes); rootTopic.add(b.topic, 0, ITopic.ATTACHED); boxes.put(t.getId(), b); } Utils.findRelationships(boxes); } } } else if (style.equals("Default")) { rootTopic.setTitleText("Central Topic"); root.topic = rootTopic; root.topic.setFolded(false); root.setDrawableShape(res.getDrawable(R.drawable.round_rect)); IStyle style3 = styleSheet.createStyle(IStyle.TOPIC); style3.setProperty(Styles.FillColor, "#CCE5FF"); style3.setProperty(Styles.ShapeClass, Styles.TOPIC_SHAPE_ROUNDEDRECT); style3.setProperty(Styles.LineClass, Styles.BRANCH_CONN_STRAIGHT); styleSheet.addStyle(style3, IStyleSheet.NORMAL_STYLES); rootTopic.setStyleId(style3.getId()); } else if (style.equals("Classic")) { rootTopic.setTitleText("Central Topic"); root.topic = rootTopic; root.topic.setFolded(false); root.setDrawableShape(res.getDrawable(R.drawable.elipse)); IStyle style2 = styleSheet.createStyle(IStyle.THEME); style2.setName("%classic"); style2.setProperty(Styles.FillColor, String.valueOf(res.getColor(R.color.light_yellow))); styleSheet.addStyle(style2, IStyleSheet.NORMAL_STYLES); sheet1.setThemeId(style2.getId()); IStyle style3 = styleSheet.createStyle(IStyle.TOPIC); style3.setProperty(Styles.FillColor, "#9ACD32"); style3.setProperty(Styles.ShapeClass, Styles.TOPIC_SHAPE_ELLIPSE); style3.setProperty(Styles.LineClass, Styles.BRANCH_CONN_CURVE); styleSheet.addStyle(style3, IStyleSheet.NORMAL_STYLES); style2.setProperty(Style.TOPIC, style3.getId()); rootTopic.setStyleId(style3.getId()); } else if (style.equals("Simple")) { rootTopic.setTitleText("Central Topic"); root.topic = rootTopic; root.topic.setFolded(false); root.setDrawableShape(res.getDrawable(R.drawable.elipse)); IStyle style2 = styleSheet.createStyle(IStyle.THEME); style2.setName("%simple"); style2.setProperty(Styles.FillColor, String.valueOf(res.getColor(R.color.white))); styleSheet.addStyle(style2, IStyleSheet.NORMAL_STYLES); sheet1.setThemeId(style2.getId()); IStyle style3 = styleSheet.createStyle(IStyle.TOPIC); style3.setProperty(Styles.FillColor, "#FFFFFF"); style3.setProperty(Styles.ShapeClass, Styles.TOPIC_SHAPE_ELLIPSE); style3.setProperty(Styles.LineClass, Styles.BRANCH_CONN_CURVE); styleSheet.addStyle(style3, IStyleSheet.NORMAL_STYLES); style2.setProperty(Style.TOPIC, style3.getId()); rootTopic.setStyleId(style3.getId()); } else if (style.equals("Business")) { rootTopic.setTitleText("Central Topic"); root.topic = rootTopic; root.topic.setFolded(false); root.setDrawableShape(res.getDrawable(R.drawable.round_rect)); IStyle style2 = styleSheet.createStyle(IStyle.THEME); style2.setName("%business"); style2.setProperty(Styles.FillColor, String.valueOf(res.getColor(R.color.white))); styleSheet.addStyle(style2, IStyleSheet.NORMAL_STYLES); sheet1.setThemeId(style2.getId()); IStyle style3 = styleSheet.createStyle(IStyle.TOPIC); style3.setProperty(Styles.FillColor, "#B87333"); style3.setProperty(Styles.ShapeClass, Styles.TOPIC_SHAPE_ROUNDEDRECT); style3.setProperty(Styles.LineClass, Styles.BRANCH_CONN_CURVE); styleSheet.addStyle(style3, IStyleSheet.NORMAL_STYLES); style2.setProperty(Style.TOPIC, style3.getId()); rootTopic.setStyleId(style3.getId()); } else if (style.equals("Academese")) { rootTopic.setTitleText("Central Topic"); root.topic = rootTopic; root.topic.setFolded(false); root.setDrawableShape(res.getDrawable(R.drawable.rect)); IStyle style2 = styleSheet.createStyle(IStyle.THEME); style2.setProperty(Styles.FillColor, "#404040"); styleSheet.addStyle(style2, IStyleSheet.NORMAL_STYLES); sheet1.setStyleId(style2.getId()); lay.setBackgroundColor(res.getColor(R.color.dark_gray)); IStyle style3 = styleSheet.createStyle(IStyle.TOPIC); style3.setProperty(Styles.FillColor, "#404040"); style3.setProperty(Styles.ShapeClass, Styles.TOPIC_SHAPE_RECT); style3.setProperty(Styles.LineClass, Styles.BRANCH_CONN_STRAIGHT); style3.setProperty(Styles.LineColor, "#FFFFFF"); styleSheet.addStyle(style3, IStyleSheet.NORMAL_STYLES); style2.setProperty(Style.TOPIC, style3.getId()); rootTopic.setStyleId(style3.getId()); } } }); } else { setContentView(R.layout.main_content_view); lay = (DrawView) findViewById(R.id.main_draw_view); lay.setZOrderOnTop(true); } gestureDetector = new GestureDetector(this, gestList); Utils.lay = lay; if (lay != null) { lay.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { detector.onTouchEvent(event); switch (event.getActionMasked()) { case (MotionEvent.ACTION_OUTSIDE): return true; case (MotionEvent.ACTION_UP): break; case MotionEvent.ACTION_POINTER_UP: if (!detector.isInProgress()) { int count = event.getPointerCount(); // Number of 'fingers' in this time Utils.getCoordsInView(lay, event, 1); boxEdited = Utils.whichBox(lay, event); float[] tab1 = Utils.getCoordsInView(lay, event, 0); float[] tab = Utils.getCoordsInView(lay, event, 1); if (count == 2 && boxEdited != null) { if (tab.length == 2) { if (mTourGuide != null) mTourGuide.cleanUp(); Box box1 = new Box(); box1.setPoint(new pl.edu.agh.mindmapex.common.Point( (int) tab[0] - (box1.getWidth() / 2), (int) tab[1] - (box1.getHeight() / 2))); AddBox addBox = new AddBox(); Properties properties = new Properties(); properties.put("box", MainActivity.boxEdited); properties.put("new_box", box1); properties.put("root", root); properties.put("res", res); properties.put("style", style); addBox.execute(properties); MainActivity.addCommendUndo(addBox); editContent(box1, addBox); lay.updateBoxWithText(box1); } } break; } default: break; } boolean response = gestureDetector.onTouchEvent(event); lay.requestFocus(); InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); in.hideSoftInputFromWindow(lay.getApplicationWindowToken(), 0); return response; } }); lay.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } Utils.context = this; this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayOptions( ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM); actionBar.show(); detector = new ScaleGestureDetector(this, new SimpleOnScaleGestureListener() { @Override public boolean onScaleBegin(ScaleGestureDetector detector) { mScaling = true; return true; } @Override public boolean onScale(ScaleGestureDetector detector) { // float focusX = detector.getFocusX(); // float focusY = detector.getFocusY(); //// lay.setPivotX(mid.x); //// lay.setPivotY(mid.y); //// lay.pivotx = (int) (lastFocusX + detector.getFocusX())/2; //// lay.pivoty = (int) (lastFocusY+ detector.getFocusY())/2; // // lay.pivotx = (int) mid.x; // // lay.pivoty = (int) mid.y; // // lay.canvas.translate(-focusX,-focusY); lay.pivotx = detector.getFocusX(); lay.pivoty = detector.getFocusY(); // lay.transx = (lay.pivotx); // lay.transy = (lay.pivoty); // lay.pivotx = (int) mid.x; // lay.pivoty = (int) mid.y; // lay.setPivotX(lastFocusX); // lay.setPivotY(lastFocusY); float SF = detector.getScaleFactor(); lay.zoomx *= SF; lay.zoomy *= SF; // lay.canvas.scale(SF, SF, mid.x, mid.y); // float focusShiftX = focusX - lastFocusX; // float focusShiftY = focusY - lastFocusY; //lay.canvas.translate(focusX + focusShiftX, focusY + focusShiftY); // lastFocusX = focusX; // lastFocusY = focusY; // lay.transy = detector.getFocusY(); // lay.zoomx = Math.max(0.1f, Math.min(lay.zoomx, 5.0f)); // lay.zoomy = Math.max(0.1f, Math.min(lay.zoomy, 5.0f)); return true; } }); progressDialog.dismiss(); lay.setId(View.generateViewId()); lay.setSaveEnabled(true); if (savedInstanceState != null) { lay.transx = savedInstanceState.getFloat(TRANSX_KEY); lay.transy = savedInstanceState.getFloat(TRANSY_KEY); lay.zoomx = savedInstanceState.getFloat(ZOOMX_KEY); lay.zoomy = savedInstanceState.getFloat(ZOOMY_KEY); lay.pivotx = savedInstanceState.getFloat(PIVOTX_KEY); lay.pivoty = savedInstanceState.getFloat(PIVOTY_KEY); } }
From source file:org.appcelerator.titanium.view.TiUIView.java
protected void registerTouchEvents(final View touchable) { touchView = new WeakReference<View>(touchable); final ScaleGestureDetector scaleDetector = new ScaleGestureDetector(touchable.getContext(), new SimpleOnScaleGestureListener() { // protect from divide by zero errors long minTimeDelta = 1; float minStartSpan = 1.0f; float startSpan; @Override/*w w w. j a v a 2 s . c o m*/ public boolean onScale(ScaleGestureDetector sgd) { if (proxy.hierarchyHasListener(TiC.EVENT_PINCH)) { float timeDelta = sgd.getTimeDelta() == 0 ? minTimeDelta : sgd.getTimeDelta(); // Suppress scale events (and allow for possible two-finger tap events) // until we've moved at least a few pixels. Without this check, two-finger // taps are very hard to register on some older devices. if (!didScale) { if (Math.abs(sgd.getCurrentSpan() - startSpan) > SCALE_THRESHOLD) { didScale = true; } } if (didScale) { KrollDict data = new KrollDict(); data.put(TiC.EVENT_PROPERTY_SCALE, sgd.getCurrentSpan() / startSpan); data.put(TiC.EVENT_PROPERTY_VELOCITY, (sgd.getScaleFactor() - 1.0f) / timeDelta * 1000); data.put(TiC.EVENT_PROPERTY_SOURCE, proxy); return proxy.fireEvent(TiC.EVENT_PINCH, data); } } return false; } @Override public boolean onScaleBegin(ScaleGestureDetector sgd) { startSpan = sgd.getCurrentSpan() == 0 ? minStartSpan : sgd.getCurrentSpan(); return true; } }); final GestureDetector detector = new GestureDetector(touchable.getContext(), new SimpleOnGestureListener() { @Override public boolean onDoubleTap(MotionEvent e) { if (proxy.hierarchyHasListener(TiC.EVENT_DOUBLE_TAP) || proxy.hierarchyHasListener(TiC.EVENT_DOUBLE_CLICK)) { boolean handledTap = proxy.fireEvent(TiC.EVENT_DOUBLE_TAP, dictFromEvent(e)); boolean handledClick = proxy.fireEvent(TiC.EVENT_DOUBLE_CLICK, dictFromEvent(e)); return handledTap || handledClick; } return false; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { Log.d(TAG, "TAP, TAP, TAP on " + proxy, Log.DEBUG_MODE); if (proxy.hierarchyHasListener(TiC.EVENT_SINGLE_TAP)) { return proxy.fireEvent(TiC.EVENT_SINGLE_TAP, dictFromEvent(e)); // Moved click handling to the onTouch listener, because a single tap is not the // same as a click. A single tap is a quick tap only, whereas clicks can be held // before lifting. // boolean handledClick = proxy.fireEvent(TiC.EVENT_CLICK, dictFromEvent(event)); // Note: this return value is irrelevant in our case. We "want" to use it // in onTouch below, when we call detector.onTouchEvent(event); But, in fact, // onSingleTapConfirmed is *not* called in the course of onTouchEvent. It's // called via Handler in GestureDetector. <-- See its Java source. // return handledTap;// || handledClick; } return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.d(TAG, "SWIPE on " + proxy, Log.DEBUG_MODE); if (proxy.hierarchyHasListener(TiC.EVENT_SWIPE)) { KrollDict data = dictFromEvent(e2); if (Math.abs(velocityX) > Math.abs(velocityY)) { data.put(TiC.EVENT_PROPERTY_DIRECTION, velocityX > 0 ? "right" : "left"); } else { data.put(TiC.EVENT_PROPERTY_DIRECTION, velocityY > 0 ? "down" : "up"); } return proxy.fireEvent(TiC.EVENT_SWIPE, data); } return false; } @Override public void onLongPress(MotionEvent e) { Log.d(TAG, "LONGPRESS on " + proxy, Log.DEBUG_MODE); if (proxy.hierarchyHasListener(TiC.EVENT_LONGPRESS)) { proxy.fireEvent(TiC.EVENT_LONGPRESS, dictFromEvent(e)); } } }); touchable.setOnTouchListener(new OnTouchListener() { int pointersDown = 0; public boolean onTouch(View view, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { lastUpEvent.put(TiC.EVENT_PROPERTY_X, (double) event.getX()); lastUpEvent.put(TiC.EVENT_PROPERTY_Y, (double) event.getY()); } scaleDetector.onTouchEvent(event); if (scaleDetector.isInProgress()) { pointersDown = 0; return true; } boolean handled = detector.onTouchEvent(event); if (handled) { pointersDown = 0; return true; } if (event.getActionMasked() == MotionEvent.ACTION_POINTER_UP) { if (didScale) { didScale = false; pointersDown = 0; } else { pointersDown++; } } else if (event.getAction() == MotionEvent.ACTION_UP) { if (pointersDown == 1) { proxy.fireEvent(TiC.EVENT_TWOFINGERTAP, dictFromEvent(event)); pointersDown = 0; return true; } pointersDown = 0; } String motionEvent = motionEvents.get(event.getAction()); if (motionEvent != null) { if (proxy.hierarchyHasListener(motionEvent)) { proxy.fireEvent(motionEvent, dictFromEvent(event)); } } // Inside View.java, dispatchTouchEvent() does not call onTouchEvent() if this listener returns true. As // a result, click and other motion events do not occur on the native Android side. To prevent this, we // always return false and let Android generate click and other motion events. return false; } }); }