Determining translationX/Y values for ObjectAnimator; how to move a view to an exact screen position?

36,615

First, userControlLayout.getLeft() is relative to the parent view. If this parent is aligned to the left edge of the screen, those values will match. For getTop() it's generally different simply because getLocationInWindow() returns absolute coordinates, which means that y = 0 is the very top left of the window -- i.e. behind the action bar.

Generally you want to translate the control relative to its parent (since it won't even be drawn if it moves outside those bounds). So supposing you want to position the control at (targetX, targetY), you should use:

int deltaX = targetX - button.getLeft();
int deltaY = targetY - button.getTop();

ObjectAnimator translateX = ObjectAnimator.ofFloat(button, "translationX", deltaX);
ObjectAnimator translateY = ObjectAnimator.ofFloat(button, "translationY", deltaY);

When you supply multiple values to an ObjectAnimator, you're indicating intermediate values in the animation. So in your case userUpTop, -userUpTop would cause the translation to go down first and then up. Remember that translation (as well as rotation and all the other transformations) is always relative to the original position.

Share:
36,615
wkhatch
Author by

wkhatch

Day Job: Sr. Software Engineer at Anaren Microve, where I'm focused on the IoT solutions we facilitate for our customers using our Atmosphere platform. Python, node and the mobile web frameworks occupy this part of my day. Previously worked as independent mobile developer on both iOS and Android. I've done lots of web development using all kinds of frameworks, mostly favoring rails, and all the way back to the best one ever that apple shouldn't have killed: WebObjects ;-)

Updated on August 21, 2022

Comments

  • wkhatch
    wkhatch over 1 year

    I'm trying to move a view to the upper right corner of the screen, using ObjectAnimator.ofFloat(...) But, I'm not getting the results I expect. I'm getting the coordinates of the view beforehand, using ViewTreeListener, etc, and I already know the x value I need to offset from the end of the overall width. I can't get either dimension to move to where I want it. Relevant code:

    Getting the starting coordinate; where the view currently is:

    int[] userCoords = new int[]{0,0};
    userControlLayout.getLocationInWindow(userCoords);
    //also tried getLocationInScreen(userCoords); same result
    userUpLeft = userCoords[0];
    userUpTop = userCoords[1];
    

    Surprisingly, I get the same value as userUpLeft (which is in screen coordinates, and not relative to parent) when I call userControlLayout.getLeft() I'd expect them to be different per my understanding of the docs. Anyway...

    Constructing the ObjectAnimators:

    //testXTranslate is a magic number of 390 that works; arrived at by trial. no idea why that 
    // value puts the view where I want it; can't find any correlation between the dimension 
    // and measurements I've got
    ObjectAnimator translateX = ObjectAnimator.ofFloat(userControlLayout, "translationX",
                                                                      testXTranslate);
    
    //again, using another magic number of -410f puts me at the Y I want, but again, no idea //why; currently trying the two argument call, which I understand is from...to
    //if userUpTop was derived using screen coordinates, then isn't it logical to assume that -//userUpTop would result in moving to Y 0, which is what I want? Doesn't happen
    ObjectAnimator translateY = ObjectAnimator.ofFloat(userControlLayout, "translationY",
                                                                      userUpTop, -(userUpTop));
    

    My understanding is that the one arg call is equivalent to specifying the end coordinate you want to translate/move to, and the two arg version is starting at...ending at, or, from...to I've messed around with both and can't get there.

    Clearly, I'm missing very fundamental knowledge, just trying to figure out what exactly that is. Any guidance much appreciated. Thanks.

  • wkhatch
    wkhatch almost 10 years
    Thank you, @matiash. userControlLayout.getTop() returns the same value as getLocationInWindow; it's not different. So, using just the Y for discussion, I want to move it to 0; all the way up top (no action bar here). If I use 0 - userControlLayout.getTop(), it only moves me up slightly, not anywhere near the top. The view I want to move is in a fragment, and has three parents; all with width/height set to fill parent...(cont)
  • wkhatch
    wkhatch almost 10 years
    ...(cont) I can get it to move where I want it using the hard coded values I mentioned (which would imply it can move outside of it's parent), but not using any calculations on coordinates and measurements I have access to. Do I need to interrogate the parent layouts for more info, and if so, what? Thanks for the reply
  • konunger
    konunger over 9 years
    Have you got an answer on your question? Asking because I have the same misunderstanding((
  • wkhatch
    wkhatch over 9 years
    @konunger Sorry, nothing definitive.