Android Kotlin-同时和/或相互重复多个动画

Android Kotlin-同时和/或相互重复多个动画,android,multithreading,android-studio,animation,kotlin,Android,Multithreading,Android Studio,Animation,Kotlin,我正在尝试在Android Studio中创建一个游戏应用程序。这个概念是:有一些圆圈落下,在触摸屏幕底部的一条线之前,你需要点击/按下它们使它们消失。为此,我创建了一个以圆为图像的ImageView。我让它出现在顶部,它以缓慢的速度向下移动。当我按下它时,它消失了。问题是,第二个圆出现在第一个圆之后,这很好,但是向下动画没有启动,OnClickListener也没有工作 以下是创建圆的代码: /*Creation of ball via imageView. ImageView is crea

我正在尝试在Android Studio中创建一个游戏应用程序。这个概念是:有一些圆圈落下,在触摸屏幕底部的一条线之前,你需要点击/按下它们使它们消失。为此,我创建了一个以圆为图像的ImageView。我让它出现在顶部,它以缓慢的速度向下移动。当我按下它时,它消失了。问题是,第二个圆出现在第一个圆之后,这很好,但是向下动画没有启动,OnClickListener也没有工作

以下是创建圆的代码:

/*Creation of ball via imageView.
ImageView is created on the current Activity Layout with the circle as image.
ImageView is 200x200 and appears in the middle of the screen (horizontal) on top.
*/
private fun drawBall(){
    val imageView = ImageView(this)
    imageView.setImageDrawable(getDrawable(R.drawable.ball_1))
    imageView.layoutParams = LinearLayout.LayoutParams(200, 200)
    imageView.x = (width/2.5).toFloat()
    layout.addView(imageView)
    moveBall(imageView)
}
以下是动画开始和圆消失的OnClickListener的代码:

//Animation of ball falling down.
private fun moveBall(imageView: ImageView){
    val valueAnimator = ValueAnimator.ofFloat(0f, height*0.68.toFloat() )
    valueAnimator.addUpdateListener {
        val value = it.animatedValue as Float
        imageView.translationY = value
    }

    valueAnimator.interpolator = LinearInterpolator()
    valueAnimator.duration = 2500
    valueAnimator.start()

    //Shooting the ball and incrementing score
    imageView.setOnClickListener(){
        imageView.visibility = View.INVISIBLE
        var currentScore = textView_score.text.toString().toInt()
        currentScore++
        textView_score.text = currentScore.toString()
    }
}
在这里,您可以找到我试图创建一个圆的多个实例的代码:

//Multiple instances of the falling ball animation.
private fun startBalls(){
    val runnable = Runnable { drawBall() }
    runnable.run(){
        drawBall()
    }

    val exec = ScheduledThreadPoolExecutor(1)
    val period : Long = 1000
    exec.scheduleAtFixedRate(runnable,0, period, TimeUnit.MILLISECONDS)
    val delay : Long = 1000
    exec.scheduleWithFixedDelay(runnable, 0, delay, TimeUnit.MILLISECONDS)
}
我想我的主要问题是我试图创建多个圆的实例。
提前感谢。

moveBall()
进行日志记录表明,当
ScheduledThreadPoolExecutor启动
Runnable
时,该代码不会在UI线程上执行。更具体地说,
valueAnimator.start()
之后的下一行根本不会执行(第一次“触摸”UI元素会导致非UI线程中出现异常),因此除了第一个
ImageView
之外,不会为所有对象设置
OnClickListener

由于在
ScheduledThreadPoolExecutor
重用
Runnable
的同一实例时也会发生这种情况,因此您可以使用自定义
Runnable
类,并让它在UI线程上调用
trablell()

class MyRunnable(val functionToInvoke: () -> Unit): Runnable {
    override fun run() {
        Handler(Looper.getMainLooper()).post(Runnable {
            //this will run on the UI thread
            functionToInvoke.invoke()
      })
    }
}
startball()中的用法

val exec = ScheduledThreadPoolExecutor(1)
val period : Long = 1000
exec.scheduleAtFixedRate(MyRunnable({drawBall()}),0, period, TimeUnit.MILLISECONDS)
val delay : Long = 1000
exec.scheduleWithFixedDelay(MyRunnable({drawBall()}), 0, delay, TimeUnit.MILLISECONDS)