Почему я не могу изменить видимость своего изображения с помощью Kotlin?

#android #kotlin

Вопрос:

Изображение меняет видимость только один раз. Я не могу понять, в чем может быть проблема.

 class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        println("Let's do it")
        val btn: ImageView = findViewById(R.id.imageView)
        while (true) {
            Handler().postDelayed({
                btn.isVisible = true
                Handler().postDelayed({
                    btn.isVisible = false
                }, 1000)
            }, 1000)
        }
    }
}
 

Комментарии:

1. Мне кажется, что вы публикуете много отложенных исполняемых файлов, так как другие postDelayed вызовы будут повторяться без задержек между ними.

2. код : создайте миллионы обработчиков и исполняемых файлов как можно быстрее … пользовательский интерфейс : кричит «дай мне передохнуть!»

3. @Майкл, как я могу все исправить? Я просто пытаюсь каждую секунду менять видимость.

4. @DanGal удалите цикл while

Ответ №1:

минимальный пример :

 class MainActivity : AppCompatActivity() {

    private lateinit var target : ImageView
    private val handler : Handler = Handler(Looper.getMainLooper())
    private val runnable : Runnable  = object : Runnable {
        override fun run() {
            target.isVisible = !target.isVisible
            handler.postDelayed(this, 1_000)
        }

    }

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

        target  = findViewById<ImageView>(R.id.imageView)

    }

    override fun onResume() {
        super.onResume()
        handler.postDelayed(runnable, 1_000)
    }

    override fun onPause() {
        super.onPause()
        handler.removeCallbacksAndMessages(null)
    }
}
 

Комментарии:

1. Могу ли я сделать задержку меньше миллисекунды?

2. Нет, и это было бы бессмысленно, учитывая, что «кадр» рисуется каждые 16 миллисекунд (60 кадров в секунду). Исполняемые файлы и обработчики не идеальны для быстрого обновления пользовательского интерфейса. Обычно вы используете Animator фреймворк или пользовательские представления и полностью контролируете холст. Не совсем уверен в вашем случае использования, чтобы задать такой вопрос.

Ответ №2:

давайте упростим этот код

         while (true) { // you will keep running this 
            Handler().postDelayed({
                ... // this code will won't be exec until 1000ms 
            }, 1000)
        }
 

Таким образом , вы можете видеть, что за 1000 мс вы добавите так много сообщений в очередь сообщений .
Хорошо, давайте посмотрим на 1000-2000 мс за этот период:
В этот период обработчик сделает две вещи :

  1. продолжайте публиковать сообщение о задержке в обработчике
  2. выполните предыдущее сообщение 1000 мс

Шаг 2 также сделает две вещи :

  1. установить видимое = true
  2. опубликуйте сообщение «сделать видимым» = ложь

Итак, давайте посмотрим на 2000-3000 мс :
на этот раз мы сделаем 3 вещи :

  1. продолжайте публиковать сообщение о задержке в обработчике
  2. выполните предыдущее сообщение 1000 мс
  3. выполните сообщение шага 2

шаг 3 сделает одну вещь: сделает вид невидимым.

Итак :
0-1000 мс : вид ничего не делает .
1000-2000 мс : вид будет установлен видимым
2000- : вид будет установлен видимым и невидимым очень быстро, так что вы не сможете определить разницу .

Ответ №3:

Вы делаете одну вещь неправильно

 btn.isVisible = true
 btn.isVisible = false
 

Это должно быть

 btn.visibility = GONE
btn.visibility = VISIBLE
 

Комментарии:

1. нет, если вы используете View.kt расширения. Это не та «единственная» вещь, которая неверна.