Как оставить imageView вне экрана [Котлин] - PullRequest
1 голос
/ 02 августа 2020

Итак, я новичок в Kotlin и пытаюсь сделать супер простое приложение. Все, что он делает, это когда я нажимаю правую кнопку, он идет вправо, как и левая кнопка. Проблема в том, что когда я нажимаю любую кнопку (например, правую кнопку), я могу щелкать по ней до тех пор, пока изображение полностью не исчезнет с экрана. Итак, как я могу реализовать код, который при попадании на край экрана перестает двигаться?

Мой код

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

Я могу нажимать, пока он полностью не исчезнет

Спасибо за помощь

1 Ответ

6 голосов
/ 03 августа 2020

Добро пожаловать в Kotlin!

Итак, у вас есть анимация Губки Боба, теперь вам нужно немного c logi для управления этой анимацией. Проблема здесь в том, что вы не всегда хотите, чтобы происходила полная анимация, верно? Если он слишком близко к краю экрана, вы хотите, чтобы кнопка перемещала его только до этой невидимой стены (и если он прямо напротив нее, это означает, что движения вообще нет).

Анимация и Системы рисования не накладывают никаких ограничений на то, где вы можете разместить View, поэтому вам решать, как это делать самостоятельно. В основном вам нужно сделать это при нажатии кнопки:

  • получить координаты положения Губки Боба (это X, который вам действительно важен прямо сейчас)
  • выработать положение края вас заботит (координаты представления описывают, где находится верхний левый угол, поэтому, если вы смотрите на правый край, вам нужна эта координата X + ширина представления)
  • выработайте координату 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())
    }
}

Th Есть более приятные вещи, которые вы можете сделать (и SpongeBob следует называть spongeBob и быть View), но это основы. Эта статья о системе координат может вам тоже помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...