multithreading - Android drag ImageView very laggy -
i trying implement touch-draggable imageview
in android app. there loads of sample codes on , elsewhere, , seem along lines of this one.
i tried similar this, laggy , kept getting warning
choreographer﹕ skipped xx frames! application may doing work on main thread.
i followed the android documentation advice on , tried work in separate thread, hasn't solved issue.
basically register ontouchlistener
view, in ontouch()
method start new thread try , work (the final update of layout params sent ui thread processing using view.post()
).
i can't see how achieve doing less work on main thread. there way fix code? or there perhaps better approach altogether?
the code:
private void settouchlistener() { final imageview insituart = (imageview)findviewbyid(r.id.insitu2art); insituart.setontouchlistener(new view.ontouchlistener() { @override public boolean ontouch(view v, motionevent event) { final motionevent event2 = event; new thread(new runnable() { @override public void run() { framelayout.layoutparams layoutparams = (framelayout.layoutparams) insituart.getlayoutparams(); switch (event2.getaction()) { case motionevent.action_down: { int x_cord = (int) event2.getrawx(); int y_cord = (int) event2.getrawy(); // remember started mlasttouchy = y_cord; mlasttouchx = x_cord; } break; case motionevent.action_move: { int x_cord = (int) event2.getrawx(); int y_cord = (int) event2.getrawy(); float dx = x_cord - mlasttouchx; float dy = y_cord - mlasttouchy; layoutparams.leftmargin += dx; layoutparams.topmargin += dy; layoutparams.rightmargin -= dx; final framelayout.layoutparams finallayoutparams = layoutparams; insituart.post(new runnable() { @override public void run() { insituart.setlayoutparams(finallayoutparams); } }); mlasttouchx = x_cord; mlasttouchy = y_cord; } break; default: break; } } }).start(); return true; } }); }
with new thread
added more choppiness drag movement. mentioned @johnwhite ontouch called lots of times in row, , creating , firing new threads really, bad.
the general reason why encountering issues begin because example code u following, event though works, it's bad unoptimised code.
every time you're calling setlayoutparams
system have execute new complete layout pass, , lot of stuff doing continuously.
i won't write code you, i'll point possible alternatives.
first remove thread logic used. you're not executing complex calculation, can run on ui-thread.
- use offsettopandbottom , offsetleftandright move imageview on screen.
- use viewtransformations settranslationx (and y)
change imageview
match_parent
, create custom imageview. in custom view you'll overrideondraw
method move image right before draw it. this:@override public void ondraw(canvas canvas) { int savecount = canvas.save(); canvas.translate(dx, dy); // values calculated ontouchlistener super.ondraw(canvas); // let image view normal draw canvas.restoretocount(savecount); // restore canvas position }
this last option interesting it's not changing layouts in absolutely no way. it's making imageview take care of whole area , moving drawing correct position. efficient way of doing.
on of options you'll need call "invalidate" on view, draw
can called again.
Comments
Post a Comment