i have days trying make work, checked out other answers , none seem work me :s
i add sticker relativelayout, want sticker move, scale , rotate ontouch methods once selected (it has onclicklistener calls setontouchlistener) keeping in mind can have n stickers added.
private void addsticker(imageview sticker) { flmemeframe.addview(sticker); sticker.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { { if (selectedview != null) { cancelselection(selectedview); } selectedview = v; v.setontouchlistener(new view.ontouchlistener() { private float mscalefactor = 0.5f; private float mrotationdegree = 0.f; private float mfocusx = 0.f; private float mfocusy = 0.f; private int mscreenheight; private int mscreenwidth; private matrix matrix = new matrix();//các lớp matrix giữ một ma trận 3x3 để di chuyển tọa độ. private int mimagewidth, mimageheight; private scalegesturedetector mscaledetector; private rotategesturedetector mrotatedetector; private movegesturedetector mmovedetector; class scalelistener extends scalegesturedetector.simpleonscalegesturelistener { @override public boolean onscale(scalegesturedetector detector) { mscalefactor *= detector.getscalefactor(); mscalefactor = math.max(0.1f, math.min(mscalefactor, 1.0f)); return true; } } class rotatelistener extends rotategesturedetector.simpleonrotategesturelistener { @override public boolean onrotate(rotategesturedetector detector) { mrotationdegree -= detector.getrotationdegreesdelta(); return true; } } class movelistener extends movegesturedetector.simpleonmovegesturelistener { @override public boolean onmove(movegesturedetector detector) { pointf d = detector.getfocusdelta(); mfocusx += d.x; mfocusy += d.y; return true; } } @override public boolean ontouch(view v, motionevent event) { mimageheight = v.getheight(); mimagewidth = v.getwidth(); mscaledetector = new scalegesturedetector(context, new scalelistener()); mrotatedetector = new rotategesturedetector(context, new rotatelistener()); mmovedetector = new movegesturedetector(context, new movelistener()); mscaledetector.ontouchevent(event); mrotatedetector.ontouchevent(event); mmovedetector.ontouchevent(event); float scaleimagecenterx = (mimagewidth * mscalefactor) / 2; float scaleimagecentery = (mimageheight * mscalefactor) / 2; matrix.reset(); matrix.postscale(mscalefactor, mscalefactor); matrix.postrotate(mrotationdegree, scaleimagecenterx, scaleimagecentery); matrix.posttranslate(mfocusx - scaleimagecenterx, mfocusy - scaleimagecentery); imageview view = (imageview) v; view.setscaletype(imageview.scaletype.matrix); view.setimagematrix(matrix); return true; } }); } } }); }
here set image
imageview sticker = new imageview(context); relativelayout.layoutparams rlp = new relativelayout.layoutparams(actionbar.layoutparams.wrap_content, actionbar.layoutparams.wrap_content); rlp.addrule(relativelayout.center_in_parent); sticker.setlayoutparams(rlp); addsticker(sticker);
the app compiles , no crashes, sticker nothing ontouch :(
links have tried:
http://code.almeros.com/android-multitouch-gesture-detectors#.v1y0szmrlmw
rotation , scaling , move using multi touch in android
and other links can't find now
anyone can help?
edit: code cancelselection (completely unrelated, thing i'm doing setting selectedview null , removing background, remove ontouchlistener, because don't want move/scale/rotate view if it's not selected)
@suppresswarnings("deprecation") public void cancelselection(view v) { if(iscaptioneditpanelopen) { rlquickedit.setvisibility(view.gone); rlquickedit = null; iscaptioneditpanelopen = false; } //tooglebuttonvisibility(false); v.setbackgroundcolor(getresources().getcolor(android.r.color.transparent)); selectedview = null; v.setontouchlistener(null); }
i wrote class, see if can make work without complexity of app, same results:
package com.andujardev.imagerotation; import android.content.context; import android.graphics.matrix; import android.graphics.pointf; import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.view.motionevent; import android.view.scalegesturedetector; import android.view.view; import android.widget.imageview; public class mainactivity extends appcompatactivity { context context; imageview imgrotate; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); context = this; imgrotate = (imageview) findviewbyid(r.id.imgrotate); imgrotate.setontouchlistener(new view.ontouchlistener() { private float mscalefactor = 0.5f; private float mrotationdegree = 0.f; private float mfocusx = 0.f; private float mfocusy = 0.f; private int mscreenheight; private int mscreenwidth; private matrix matrix = new matrix(); private int mimagewidth, mimageheight; private scalegesturedetector mscaledetector; private rotategesturedetector mrotatedetector; private movegesturedetector mmovedetector; class scalelistener extends scalegesturedetector.simpleonscalegesturelistener { @override public boolean onscale(scalegesturedetector detector) { mscalefactor *= detector.getscalefactor(); mscalefactor = math.max(0.1f, math.min(mscalefactor, 1.0f)); return true; } } class rotatelistener extends rotategesturedetector.simpleonrotategesturelistener { @override public boolean onrotate(rotategesturedetector detector) { mrotationdegree -= detector.getrotationdegreesdelta(); return true; } } class movelistener extends movegesturedetector.simpleonmovegesturelistener { @override public boolean onmove(movegesturedetector detector) { pointf d = detector.getfocusdelta(); mfocusx += d.x; mfocusy += d.y; return true; } } @override public boolean ontouch(view v, motionevent event) { mimageheight = v.getheight(); mimagewidth = v.getwidth(); mscaledetector = new scalegesturedetector(context, new scalelistener()); mrotatedetector = new rotategesturedetector(context, new rotatelistener()); mmovedetector = new movegesturedetector(context, new movelistener()); mscaledetector.ontouchevent(event); mrotatedetector.ontouchevent(event); mmovedetector.ontouchevent(event); float scaleimagecenterx = (mimagewidth * mscalefactor) / 2; float scaleimagecentery = (mimageheight * mscalefactor) / 2; matrix.reset(); matrix.postscale(mscalefactor, mscalefactor); matrix.postrotate(mrotationdegree, scaleimagecenterx, scaleimagecentery); matrix.posttranslate(mfocusx - scaleimagecenterx, mfocusy - scaleimagecentery); imageview view = (imageview) v; view.setimagematrix(matrix); return true; } }); } }
it's interesting every ontouch
event instantiate new scalegesturedetector
, rotategesturedetector
, , movegesturedetector
.
considering each respective gesture detector needs previous touch event determine , interpret how react decidedly significant part of issue since create new gesture detector each touch event. in fact if in source almeros
detector ontouchevent(motionevent ev)
method states:
applications should pass complete , consistent event stream method. * complete , consistent event stream involves motionevents initial * action_down final action_up or action_cancel.
for starters should ensure creating single detector object can consume touch events.