multithreading - Android drag ImageView very laggy -


i trying implement touch-draggable imageviewin 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.

  1. use offsettopandbottom , offsetleftandright move imageview on screen.
  2. use viewtransformations settranslationx (and y)
  3. change imageview match_parent , create custom imageview. in custom view you'll override ondraw 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

Popular posts from this blog

Email notification in google apps script -

c++ - Difference between pre and post decrement in recursive function argument -

javascript - IE11 incompatibility with jQuery's 'readonly'? -