Luis Sieira
Luis Sieira

Reputation: 31522

How to force View to recalculate it's position after changing parent

It has been some days since I have this problem.

This is a reformulation of this question considering the behavior I describe on this answer. Please, note that this question states for a less specific case, and the answer could be useful for many different scenarios.

I'm moving one chip from the left point to the right point, and writing original and new coordinates:

backgammon beforebackgammon after

So this is failing:

public void onTouch(View view) {
    int[] aux = new int[2];

    //Get the chip
    View movingChip = findViewById(R.id.c1);
    //Write it's coordinates
    movingChip.getLocationOnScreen(aux);
    ((TextView)findViewById(R.id.p1t1)).setText("(" + aux[0] + "," + aux[1] + ")");
    //Move it
    ((LinearLayout)findViewById(R.id.p1)).removeView(movingChip);
    ((LinearLayout)findViewById(R.id.p2)).addView(movingChip);
    movingChip.requestLayout();//#### Adding this didn't solve it

    //Write it's coordinates
    movingChip.getLocationOnScreen(aux);
    ((TextView)findViewById(R.id.p2t4)).setText("(" + aux[0] + "," + aux[1] + ")");
}

When I get the coordinates for the second time, I get the coordinates of the view as if it was positioned in the new parent at the same place it was in the old one

So, new top, left, bottom, right etc... are not being calculated at this point. On the other hand, my views are displayed properly, so this job is getting done at some point. How could I force this calculation to happen ?

I need to do it this way, because I'll want to trigger a transition animation

Upvotes: 2

Views: 618

Answers (2)

Luis Sieira
Luis Sieira

Reputation: 31522

Solution based on Dalija's suggestion

public class ChipView extends ImageView {
    private int[] currentLocation = new int[2];
    /*.....
      * blah,blah,blah
      * .....*/

    public void init() {
        this.addOnLayoutChangeListener(new OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                int[] newLocation = new int[2];
                v.getLocationOnScreen(newLocation);
                Log.d("New location:", "("+newLocation[0]+","+newLocation[1]+")");
                /** Do whatever is needed with old and new locations **/
                currentLocation = newLocation;
            }
        });
    }

So, init() is called from the constructor; now I'll try to perform the animation from there, but this is a different tale.I hope it will work.

Upvotes: 0

Dalija Prasnikar
Dalija Prasnikar

Reputation: 28516

I would suggest using OnLayoutChangeListener to capture your chip movements. Of course, you will have to attach those listeners outside onTouch event

    chip.addOnLayoutChangeListener(new OnLayoutChangeListener()
    {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
        {

        }
    });

Upvotes: 1

Related Questions