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

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

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -