How to move a view in Android?

21,873

Solution 1

WindowManager maintains at least two more instances of LayoutParams class for each view, besides that one in the View itself.

Check updateViewLayout method of WindowManager, this part in particular:

    view.setLayoutParams(wparams);

    synchronized (this) {
        int index = findViewLocked(view, true);
        ViewRoot root = mRoots[index];
        mParams[index] = wparams;
        root.setLayoutParams(wparams, false);
    }

I believe that you can make some mess by calling layout directly. Use WindowManager.updateViewLayout instead. It will be slower, but safe (just IMO).


UPDATE

[From: https://stackoverflow.com/a/11188273/327011 ]

WindowManager windowsManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)

WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams();
windowParams.x = <new X coord>;
windowParams.y = <new Y coord>
windowParams.height = myImageView.getHeight();
windowParams.width = myImageView.getWidth();
windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
windowParams.format = PixelFormat.TRANSLUCENT;
            windowParams.windowAnimations = 0;

windowManager.updateViewLayout(myImageView, windowParams);

Solution 2

The easiest way to move a view with the finger is using the setTranslationX and setTranslationY from the View class.

http://developer.android.com/reference/android/view/View.html#setTranslationX(float)

You can also change the margins on the View LayoutParams to move if you are targeting api < 11.

I believe that moving the item on the onLayout or onDraw function worse because the view already has these options above and drawing your view manually can become complex as you add more items and different views.

Solution 3

You could use object animation

/**
 * The java class is used to move the widgets to the region of the touch point from its original position
 * 
 * @author gfernandes
 *
 */
public class animate {

/**
 * Variable declaration
 * 
 */
    private ObjectAnimator animation1;
    private ObjectAnimator animation2;


/**
 * Function animate: Animates the widget Eg:Button from its position to the 
 *                   position of the touch point.
 *
 * @param[in] -The coordinates of the touch point (x, y)
 *            -The coordinates of the widget position (valx, valy)
 *            -The widget object id
 *                      
 */

public void animategroup1(int x, int y, Object val, int valx, int valy ){

    System.out.println("animategroup1 entered here");
    System.out.println("x:"+x);
    System.out.println("y"+y);
    System.out.println("valx"+valx);
    System.out.println("valy"+valy);

    animation1 = ObjectAnimator.ofFloat(val, "x", valx, x);

    animation2 = ObjectAnimator.ofFloat(val, "y", valy, y);

    AnimatorSet set = new AnimatorSet();

    set.playTogether(animation1, animation2);

    set.start();

 }

}
Share:
21,873
neteinstein
Author by

neteinstein

you can also call me Pedro Vicente I wake up everyday and try to turn code into magic. Want to contact me? My Website | LinkedIn | neteinstein at gmail dot com

Updated on November 04, 2020

Comments

  • neteinstein
    neteinstein over 3 years

    I have a project where I have 2 challenges:

    First:

    • Move an icon to wherever the finger touches the screen:

    For this, the best approach I've found, is to use .layout() method on the view.

    Second:

    • I have two layouts, on a RelativeLayout, both with screen width and height (1 is hidden behind the other). I want to move the one above a few dips to the right every time I click a button.

    Is there a better way to move views on Android?

    What could be the disadvantages of using the method .layout() ?

    public void layout (int l, int t, int r, int b) 
    Since: API Level 1 
    Assign a size and position to a view and all of its descendants 
    
    Parameters:
    l  Left position, relative to parent 
    t  Top position, relative to parent 
    r  Right position, relative to parent 
    b  Bottom position, relative to parent  
    

    Thanks in advance.

  • neteinstein
    neteinstein over 11 years
    You suggest I use something like this stackoverflow.com/a/11188273/327011 right?
  • Andrey Voitenkov
    Andrey Voitenkov over 11 years
    Yes, it looks like what I mean. I use similar technic when implementing drag-n-drop for Android 2.x.
  • neteinstein
    neteinstein over 11 years
    That seems very nice.. but for only API level 11 and above... what about below 11 ?
  • Marcio Covre
    Marcio Covre over 11 years
    Before 11 I think it's best to translate using the margins, to do so you need to get the LayoutParams from the view, change them and set it back to the view. You may need to call invalidate to update the view.
  • neteinstein
    neteinstein over 11 years
    Do you think this is better then the answer given by Andrey above?
  • neteinstein
    neteinstein about 11 years
    It's a nice options... but its quite recent: API 11.
  • mlkwrz
    mlkwrz about 11 years
    @NeTeInStEiN, try using nine old android library then - "Android library for using the Honeycomb (Android 3.0) animation API on all versions of the platform back to 1.0!"
  • Atmaram
    Atmaram over 9 years
    You can use nineoldandroids jar file for older version . It has ViewHelper.setTransalationX() and Y() method which will work similar to view.setTranslationX() and Y() works.
  • Jan Dolejsi
    Jan Dolejsi over 4 years
    There is a small typo in the class name first time it is mentioned.