如何在更改父项后强制 View 重新计算其位置

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

我已经好几天没遇到这个问题了。

这是 this question considering the behavior I describe on this answer 的重新表述。请注意,此问题针对的是一个不太具体的案例,答案可能对许多不同的场景都有用。

我正在从左点向右点移动一个筹码,并写下原始坐标和新坐标:

所以这是失败的:

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] + ")");
}

当我第二次获得坐标时,我得到了视图的坐标,就好像它定位在新父级中它在旧父级中的相同位置

因此,此时不计算新的顶部、左侧、底部、右侧等...。 另一方面,我的视图显示正确,所以这项工作在某个时候完成了。我怎样才能强制执行此计算?

我需要这样做,因为我要触发过渡动画

我建议使用 OnLayoutChangeListener 来捕捉您的筹码移动。当然,您必须在 onTouch 事件

之外附加这些侦听器
    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)
        {

        }
    });

根据 Dalija 的建议解决

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;
            }
        });
    }

因此,从构造函数中调用了 init();现在我将尝试从那里执行动画,但这是不同的 tale.I 希望它会起作用。