Кнопка требует двойного щелчка, чтобы активировать событие щелчка

Эту ошибку невозможно исправить, и теперь она преследует меня в двух разных проектах (первый я выбросил). ниже приведен код:


   


    if (testIterator.hasNext()){

        layers.setDrawableByLayerId(R.id.layer1, testIterator.next())
        basePicture.setImageDrawable(layers)
    }
    else{
        hairButton.isFocusable = false

        layers.setDrawableByLayerId(R.id.layer1,test.first())
        basePicture.setImageDrawable(layers)
        testIterator = test.iterator()

    }

}

«слои» — это layer-list.xml в папке с возможностью рисования. С помощью этого итератора я перебираю массив рисунков (?) под названием «тест». Drawables внутри «теста» заменяют отдельный drawable внутри моего layer-list.xml.

функция операторов if заключается в том, чтобы (как указано выше) перебирать список рисунков (?) и заменять текущий следующим, если пользователь снова нажимает кнопку. Это также должно изменить графику на экране при нажатии кнопки.

Функция оператора else состоит в том, чтобы вернуться к элементу [0] списка массивов "test" после того, как кнопка была нажата до последней функции (например, перезапуск).

Проблема: Мне нужно дважды щелкнуть кнопку, чтобы она вышла из элемента [0] и начала итерацию. После этого НЕ требуется двойной тап, по крайней мере, пока он не вернется к элементу [0]. Я исследовал эту проблему, и некоторые сказали, что это связано с «фокусом», но я много экспериментировал с фокусируемостью и не думаю, что проблема в этом.

Я не думаю, что это строка, в которой говорится: "basePicture.setImageDrawable(слои)" Я не думаю, что это проблема, потому что мне (думаю) это нужно, чтобы обновить то, как изображение выглядит на экране, и когда я комментирую эту строку, это не имеет значения.

P.S. когда я повторяю, он не сразу появляется на экране. Мне нужно нажать кнопку «Домой» (чтобы приложение исчезло) и снова открыть его, чтобы увидеть любые изменения в отображаемой графике. Это новая ошибка, которую я обнаружил, поэтому я еще не начал ее изучать, но любые идеи о том, что это такое, были бы действительно полезны. Спасибо!

Почему бы не использовать свойство индекса вместо итератора? Зависание на итераторе в долгосрочной перспективе не очень надежно.

Tenfour04 11.12.2020 03:52

@Tenfour04 Tenfour04 Как цикл for с разрывами, прикрепленными к clicklistener?

CodeCoolMath 11.12.2020 06:05

Ни о каких петлях я не думал. Вы бы не смогли сделать это без какой-то запутанной реализации сопрограммы. Просто держитесь за ссылку на последний использованный индекс. Увеличивайте его при использовании, перекатывая его, когда он достигает размера коллекции.

Tenfour04 11.12.2020 15:15
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
140
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это потому, что когда вы возвращаетесь к началу (в вашем предложении else), вы устанавливаете изображение для отображения первого слоя, а затем создаете новый итератор для следующего цикла.

Но на самом деле вы не берете первый элемент из итератора, поэтому при следующем щелчке он вызывает next(), который создает следующий элемент, то есть первый, который является первым слоем. Вы в конечном итоге показываете это снова.

Самое простое решение — просто вызвать next() после повторного создания итератора, удалить тот первый элемент, который вам не нужен. Лучшим способом было бы переместить код отображения в общую функцию:

fun showNextLayer() {
    layers.setDrawableByLayerId(R.id.layer1, testIterator.next())
    basePicture.setImageDrawable(layers)
}

...

if (!testIterator.hasNext()) {
    hairButton.isFocusable = false
    testIterator = test.iterator()
}
showNextLayer()

Вы также можете свернуть свой собственный бесконечный итератор, поэтому вам не нужно его проверять или создавать заново, и вы можете просто вызывать next() при каждом нажатии

class LayerIterator : Iterator<Int> {
    private var current = -1

    override fun hasNext() = true

    override fun next(): Int {
        // increment the current index, wrapping back to zero
        current = (current + 1) % layers.size
        return layers[current]
    }
}

но поскольку вы находитесь в Котлине, вы можете просто сделать бесконечную последовательность!

val iterator = generateSequence(0) { (it + 1) % layers.size }
    .map(layers::get)
    .iterator()

редактировать - ваша проблема с тем, что вещи не отображаются ... Я не использовал их лично, но я думаю, вам нужно использовать LevelListDrawable , а не LayerDrawable.

Последний в основном представляет собой коллекцию, которая объединяет кучу рисунков в один комбинированный визуальный элемент, на который вы можете легко ссылаться, я не думаю, что он создан для переключения того, какой из них находится сверху. Но LevelListDrawable предназначен для присвоения значений набору рисунков, а затем вы вызываете setLevel его, чтобы контролировать, какой из них отображается. (Пример, который они дают, относится к значку батареи и его различным состояниям.)

Таким образом, вам просто нужно установить этот чертеж на basePicture один раз, а затем установить рисуемый объект level, чтобы изменить то, что отображается.

Я попробовал Levellist, но у меня возникла проблема. Я пытаюсь изменить слои рисунков на разные изображения, например, когда вы настраиваете персонажа, вы можете изменить его прическу (вы также можете изменить форму носа). Я попытался создать один слой, в котором каждый элемент можно было бы рисовать в списке уровней. когда я устанавливаю свои основные изображения в список слоев, я не вижу изменений. Также я попробовал бесконечную последовательность, но она не позволила мне получить размер списка уровней. Как вы думаете, я должен попытаться использовать Canvas вместо идеи со списком слоев. @cactustictacs

CodeCoolMath 11.12.2020 21:43

О, так вы на самом деле рисуете стопку рисунков, а не по одному? Хорошо, я думаю, вам нужен LayerDrawable в этом случае, поэтому ваш исходный код должен быть в порядке, за исключением того, что вам не нужно повторно устанавливать его basePicture - вы устанавливаете список слоев как его рисуемый один раз, затем вы можете просто возиться с сам список слоев. Это должно просто работать (я не использовал их, но все же) - вы можете попробовать вызвать invalidate() на ImageView, но это должно быть автоматически. Не беспокойтесь о Canvases, если вам это не нужно. А для последовательностей, которые вам нужны, длина/размер test, ваш источник

cactustictacs 12.12.2020 02:03

Другие вопросы по теме