Эту ошибку невозможно исправить, и теперь она преследует меня в двух разных проектах (первый я выбросил). ниже приведен код:
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 Tenfour04 Как цикл for с разрывами, прикрепленными к clicklistener?
Ни о каких петлях я не думал. Вы бы не смогли сделать это без какой-то запутанной реализации сопрограммы. Просто держитесь за ссылку на последний использованный индекс. Увеличивайте его при использовании, перекатывая его, когда он достигает размера коллекции.
Это потому, что когда вы возвращаетесь к началу (в вашем предложении 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
О, так вы на самом деле рисуете стопку рисунков, а не по одному? Хорошо, я думаю, вам нужен LayerDrawable
в этом случае, поэтому ваш исходный код должен быть в порядке, за исключением того, что вам не нужно повторно устанавливать его basePicture
- вы устанавливаете список слоев как его рисуемый один раз, затем вы можете просто возиться с сам список слоев. Это должно просто работать (я не использовал их, но все же) - вы можете попробовать вызвать invalidate()
на ImageView
, но это должно быть автоматически. Не беспокойтесь о Canvas
es, если вам это не нужно. А для последовательностей, которые вам нужны, длина/размер test
, ваш источник
Почему бы не использовать свойство индекса вместо итератора? Зависание на итераторе в долгосрочной перспективе не очень надежно.