android - 如何使imageView脱离屏幕[Kotlin]

标签 android kotlin

所以我是Kotlin的新手,我正在尝试制作一个 super 简单的应用程序。它所做的就是当我单击“向右”按钮时它与向左按钮一样向右移动。问题是当我单击任一按钮(例如,右键)时,我可以单击它,直到图像完全脱离屏幕为止。那么,如何实现一个代码,一旦它到达屏幕边缘,它就会停止移动?
我的密码

package com.example.change_position_circle

import android.animation.ObjectAnimator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

        //val picture = findViewById<ImageView>(R.id.SpongeBob)
        val right_button = findViewById<Button>(R.id.right)
        val left_button = findViewById<Button>(R.id.left)


        right_button.setOnClickListener()
        {
            //ObjectAnimator.ofFloat(SpongeBob, "x", 100)

            SpongeBob.animate().setDuration(90).translationXBy(100f)
        }

        left_button.setOnClickListener()
        {
            //ObjectAnimator.ofFloat(SpongeBob, "translationXBy", 100f).apply {
            //duration = 200
            // start()
            SpongeBob.animate().setDuration(90).translationXBy(-100f)
            //}
        }
    }
}
I can keep clicking until it goes completely offscreen
谢谢您的帮助

最佳答案

欢迎来到 Kotlin !
是的,您已经制作了海绵宝宝动画,现在需要一些逻辑来控制该动画。这里的问题是您不总是希望整个动画都发生,对吗?如果他离屏幕边缘太近,则您希望按钮仅将他移动到该看不见的墙壁(如果他正对着它,则表示完全没有移动)。
动画和绘图系统对放置View的位置没有任何限制,因此您可以自行处理。单击按钮时,基本上需要这样做:

  • 获取海绵宝宝的位置坐标(这是您现在真正关心的X)
  • 计算出您关心的边缘的位置( View 的坐标描述了左上角的位置,因此,如果您在查看右边缘,则需要X坐标+ View 的宽度)
  • 计算屏幕边缘(或父布局,无论您希望将海绵宝宝包含在其中的任何位置)的X坐标
  • 如果海绵宝宝边缘和屏幕边缘之间的距离小于正常的动画运动,则需要将其更改为剩余的距离
  • 您还需要计算出合适的持续时间,如果他的移动距离是通常距离的一半,则动画的耗时应为
  • 的一半

    有很多工作要做,有几种方法可以完成,但是这是一种只使用屏幕边缘作为界限的方法
        import android.os.Bundle
    import android.view.View
    import android.widget.Button
    import androidx.appcompat.app.AppCompatActivity
    import kotlin.math.abs
    import kotlin.math.min
    
    private const val MOVE_DISTANCE = 100
    private const val MOVE_TIME = 90
    
    class MainActivity : AppCompatActivity() {
        private var screenWidth = 0
        private lateinit var spongeBob : View
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.spongebob)
    
            // store this when the Activity is created, if the device is rotated the Activity
            // will be recreated and this method gets run again
            screenWidth = applicationContext.resources.displayMetrics.widthPixels
    
            //val picture = findViewById<ImageView>(R.id.SpongeBob)
            val right_button = findViewById<Button>(R.id.right)
            val left_button = findViewById<Button>(R.id.left)
            spongeBob = findViewById(R.id.spongeBob)
    
            right_button.setOnClickListener()
            {
                // two possible values - the distance to the edge, and the normal amount we move
                // we want the smaller of the two (i.e. always move the normal amount, unless
                // the edge is closer than that
                val distance = min(distanceToEdge(left = false), MOVE_DISTANCE)
                moveSpongeBob(distance)
            }
    
            left_button.setOnClickListener()
            {
                val distance = min(distanceToEdge(left = true), MOVE_DISTANCE)
                // we're moving left so we need to use a negative distance
                moveSpongeBob (-distance)
            }
        }
    
        private fun distanceToEdge(left: Boolean): Int {
            // Get the Spongebob's top-left position - the call is a method on the View class,
            // I'm assuming SpongeBob is a View, and you need to pass an array in because
            // that's just how it works for whatever reason...
            val location = IntArray(2)
            spongeBob.getLocationOnScreen(location)
            val x = location[0]
    
            // I'm just using the View.getWidth() call here (Kotlin style) but I don't know
            // what the SpongeBob class is, so you'll need to handle this
            // You could set this once, like when we get the screen width, but width will be 0 until
            // the View is laid out - so you can't do it in #onCreate, #onViewCreated should work
            val spongeBobWidth = spongeBob.width
    
            // the left edge is just the x position, however far that is from zero
            return if (left) x
            // the right edge is the x position plus the width of the bob
            else screenWidth - (x + spongeBobWidth)
        }
    
        // Actually move the view, by the given distance (negative values to move left)
        private fun moveSpongeBob(distance: Int) {
            // work out how much this distance relates to our standard move amount, so we can
            // adjust the time by the same proportion - converting to float so we don't get
            // integer division (where it's rounded to a whole number)
            val fraction = distance.toFloat() / MOVE_DISTANCE
            // distance can be negative (i.e. moving left) so we need to use the abs function
            // to make the duration a postitive number
            val duration = abs(MOVE_TIME * fraction).toLong()
            spongeBob.animate().setDuration(duration).translationXBy(distance.toFloat())
        }
    }
    
    您可以做更好的事情(SpongeBob应该称为spongeBob,应该是View),但这就是基础。坐标系上的This article可能也会对您有所帮助。

    关于android - 如何使imageView脱离屏幕[Kotlin],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63220806/

    相关文章:

    java - 在 redir 之后只接收少量的 UDP 数据包。 (安卓模拟器)

    java - 在 Android CallLogCalls 中使用 PHONE_ACCOUNT_ID 识别 SIM 卡插槽

    Kotlin 警告 : accessing non-final property in constructor

    java - Firestore order by 和 limit 在 kotlin 中不起作用

    java - Android 的奇怪行为

    android - SomeApp "is never used"

    android - 如何忽略 Android Studio Log 中的所有硬编码字符串?

    intellij-idea - 如何抑制有关命名约定的警告?

    kotlin - 如何使 "inappropriate blocking method call"合适?

    android gradle 错误 : Can't register given path of type 'SOURCE' because it's out of content root