BraveSentry
BraveSentry

Reputation: 349

Animation moves View to wrong position

I want to move an ImageView to the center of a Button. For doing so, I use the following code:

    var leftPos = mButtonView.left.toFloat()
    var rightPos = mButtonView.right.toFloat()
    var topPos = mButtonView.top.toFloat()
    var bottomPos = mButtonView.bottom.toFloat()

    var centerX = (leftPos + rightPos)/2
    var centerY = (topPos + bottomPos)/2

    var soultoX = ObjectAnimator.ofFloat(mContentView, "x", centerX).apply {
        duration = 1000
    }

    var soultoY = ObjectAnimator.ofFloat(mContentView, "y", centerY).apply {
        duration = 1000
    }

    fun soulToButton() = AnimatorSet().apply {
        play(soultoX).with(soultoY)
        start()
    }

On calling soulToButton(), instead of moving to the expected point in the middle of mButtonView, mContentView moves to the upper left corner of the screen. Any idea why?

Upvotes: 0

Views: 155

Answers (1)

Akaki Kapanadze
Akaki Kapanadze

Reputation: 2672

I think the problem is - finding the coordinates/size of an Android View during screen construction. To get the coordinates/size of a View as soon as it is known, attach a listener to its ViewTreeObserver.

For example:

   override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val buttonView = btn
        val contentView = img

        object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                contentView.viewTreeObserver.removeOnGlobalLayoutListener(this)

                var leftPos = buttonView.left.toFloat()
                var rightPos = buttonView.right.toFloat()
                var topPos = buttonView.top.toFloat()
                var bottomPos = buttonView.bottom.toFloat()

                var centerX = (leftPos + rightPos - contentView.width) / 2
                var centerY = (topPos + bottomPos - contentView.height) / 2

                var soultoX = ObjectAnimator.ofFloat(contentView, "x", centerX).apply {
                    duration = 1000
                }

                var soultoY = ObjectAnimator.ofFloat(contentView, "y", centerY).apply {
                    duration = 1000
                }

                fun soulToButton() = AnimatorSet().apply {
                    play(soultoX).with(soultoY)
                    start()
                }

                soulToButton()
            }
        }.run {
            contentView.viewTreeObserver.addOnGlobalLayoutListener(this)
        }
    }

Upvotes: 1

Related Questions