开发者

imageview does not move on touch event android

开发者 https://www.devze.com 2023-04-12 21:04 出处:网络
MY imageview does not move when ontouch event is called...Though I can see ACTION_UP and ACTION_MOVE happening from the log traces.

MY imageview does not move when ontouch event is called...Though I can see ACTION_UP and ACTION_MOVE happening from the log traces.

Here is my code:-

public boolean onTouch(View v, MotionEvent motion) {



     float dy ;
     float dx;
     double r = 0;
     float angle = 0;

     switch(v.getId())
     {
        case R.id.arrow:
            switch(motion.getActionMasked())
            {
                case MotionEvent.ACTION_MOVE:
                    Log.w(this.getClass().getName(),"In MOTION MOVE");
                    mX1 = motion.getX();
                    mY1 = motion.getY();
                    break;

               case MotionEvent.ACTION_UP:

                  Log.w(this.getClass().getName(),"In MOTION UP");
                  mX2 = motion.getX();
                  mY2 = motion.getY();
                dy = -( mY2-mY1);
                dx = -(mX2-mX1);
                r = Math.atan2(dy, dx);
                   angle = (int)Math.toDegrees(r);
                   updateRotation(angle);
                   break;

               default:
                   break;
            }

            Log.d(this.getClass().getName(), "Value of angle in ontouch: " + Double.toString(angle));

            break;

        default:
            break;
     }
    return true;
}

Basically I am trying to calculate the angular displacement when user touches the imageview and changes its position.

====================================== Edit:- Below is my update rotation function:-

public void updateRotation(double angle)

{

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.arrow);
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    String filePath = null;
    Matrix mtx = new Matrix();

    Log.d(this.getClass().getName(), "Value: " + Double.t开发者_运维问答oString(angle));

    if(angle > 90)
        angle = 90;
    mtx.postRotate((float) angle);

    bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
    Drawable draw =new BitmapDrawable(bitmap);


    mImageView.setBackgroundDrawable(draw);
    }

=========================================================

Edit 2: Modified function

public boolean onTouch(View v, MotionEvent motion) {



     float dy ;
     float dx;
     double r = 0;


     switch(v.getId())
     {
        case R.id.arrow:
            switch(motion.getActionMasked())
            {
            case MotionEvent.ACTION_DOWN:
                mX1 = motion.getX();
                mY1 = motion.getY();
                break;

                case MotionEvent.ACTION_MOVE:
                    Log.w(this.getClass().getName(),"In MOTION MOVE");
                    mX1 = motion.getX();
                    mY1 = motion.getY();
                    break;

               case MotionEvent.ACTION_UP:

                  Log.w(this.getClass().getName(),"In MOTION UP");
                  mX2 = motion.getX();
                  mY2 = motion.getY();
                dy = -( mY2-mY1);
                dx = -(mX2-mX1);
                r = Math.atan2(dy, dx);
                   mAngle = (int)Math.toDegrees(r);
                   updateRotation();
                   break;

               default:
                   break;
            }

            Log.d(this.getClass().getName(), "Value of angle in ontouch: " + Float.toString(mAngle));

            break;

        default:
            break;
     }
    return true;
}

=============================================

Edit 3:- Strange thing is that if i modify my onTouch event and perform all the calculations in ACTION_MOVE the imageview responds for each touch event, but this is not what I want as I cannot do the proper angluar rotation in ACTION_MOVE event


Ruchira,

From looking at your code and working with many onTouch innovations myself, I can tell you that the problem is definitely in your onTouchEvent(). You record the mX1 and mY1 in your ACTION_MOVE without recording the original ACTION_DOWN event. This means that every time you move your finger, the onTouchEvent() method thinks that this is the original position. Try this instead:

public boolean onTouch(View v, MotionEvent motion) {
     float dy ;
     float dx;
     double r = 0;
     float angle = 0;

     switch(v.getId())
     {
        case R.id.arrow:
            switch(motion.getActionMasked())
            {
               case MotionEvent.ACTION_DOWN:
                    mX1 = motion.getX();
                    mY1 = motion.getY();
                    break;
               case MotionEvent.ACTION_MOVE:
                    Log.w(this.getClass().getName(),"In MOTION MOVE");
               //Just to support real time rotation, you could:
                    mX2 = motion.getX();
                    mY2 = motion.getY();
                    //... some rotation code.
                    break;

               case MotionEvent.ACTION_UP:
                   Log.w(this.getClass().getName(),"In MOTION UP");
              // All of this should be fine.
                   mX2 = motion.getX();
                   mY2 = motion.getY();
                   dy = -( mY2-mY1);
                   dx = -(mX2-mX1);
                   r = Math.atan2(dy, dx);
                   angle = (int)Math.toDegrees(r);
                   updateRotation(angle);
                   break;

               default:
                   break;
            }

            Log.d(this.getClass().getName(), "Value of angle in ontouch: " + Double.toString(angle));

            break;

        default:
            break;
    }
    return true;
}

That should at least track your numbers correctly, so that they may actually be used.

Additional Considerations The most common mistake is to make sure that you have not set any of your tracking variables to final. If this is the case, the code will set it once, but not again...

When dealing with Drawables, it is important to get rid of the original Drawable and its callback. The reason for this is a well known issue that was never resolved in Android because a decision couldn't be made as to when exactly it was necessary and when it wasn't. Essentially, Android will eventually run out of memory, but will not necessarily tell you and just fail to update the image. This is how you do this (when replacing an image).

Drawable trash = mImageView.getBackgroundDrawable();
if (trash != null)
{   trash.setCallback(null);
    trash.recycle();
    trash = null;
}
mImageView.setBackgroundDrawable(draw);

Finally, you have to let the image know that it has to redraw itself. This isn't always the case, but is true more often than not. mImageView.invalidate(); will often resolve the issue, and should be placed on the last line in your updateRotation() method.

FuzzicalLogic

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号