Ошибка setVisibility в Android P: метод можно вызывать только из той же библиотечной группы
Причина ошибки
Ошибка VisibilityAwareImageButton.setVisibility can only be called from the same library group возникает из-за механизма изоляции библиотечных групп (Library Groups), введённого в Android 9.0 Pie. Система проверяет, что методы, изменяющие состояние виджетов из библиотеки Material Design (группа com.google.android.material), вызываются только из кода, принадлежащего той же библиотечной группе. Это сделано для предотвращения некорректного изменения состояния компонентов из стороннего кода.
Проблема в том, что VisibilityAwareImageButton — это внутренний класс Material Components, который наследуется от AppCompatImageButton. Когда вы пишете myButton.visibility = View.GONE, вы вызываете сеттер setVisibility(), который в этом классе переопределён с проверкой на библиотечную группу. Если ваш код находится в приложении (группа по умолчанию), а не в самой библиотеке Material, система блокирует вызов.
Решение: Используйте правильные методы
Вместо прямого обращения к свойству visibility используйте методы, предоставляемые Material Components, которые корректно обрабатывают эту проверку:
// Вместо этого:
myButton.visibility = View.GONE
// Используйте это:
myButton.isVisible = false // для MaterialButton
// или
myButton.hide() // если есть метод hide()
Для MaterialButton (который вы используете в XML) правильный способ — работать через свойство isVisible или методы show()/hide():
class MyFragment : Fragment() {
private lateinit var myButton: MaterialButton
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
myButton = view.findViewById(R.id.my_button)
// Правильный способ:
myButton.isVisible = false // скрыть кнопку
// или
myButton.hide() // альтернативный метод
}
}
Почему это работает?
Методы show(), hide() и свойство isVisible внутри себя вызывают setVisibility() с правильным контекстом библиотечной группы. Они являются частью публичного API Material Design и не вызывают ошибку изоляции.
Дополнительные рекомендации
- Всегда используйте тип
MaterialButtonвместоVisibilityAwareImageButtonв своём коде. Если вы получаете кнопку черезfindViewById, указывайте правильный тип. - Обновите зависимости — убедитесь, что вы используете последнюю версию Material Components (например, 1.6.0+), где такие баги исправлены.
- Избегайте прямого доступа к внутренним классам —
VisibilityAwareImageButton— это внутренний класс библиотеки, его не следует использовать напрямую.
Если проблема остаётся
В редких случаях может потребоваться обновить Android SDK и пересобрать проект. Также проверьте, что в вашем build.gradle правильно указана зависимость:
dependencies {
implementation 'com.google.android.material:material:1.9.0' // последняя версия
}
После применения этих изменений ошибка должна исчезнуть, и кнопка будет корректно скрываться/показываться на Android 9 и выше.
<<Альтернативный подход: Использование View.GONE через рефлексию
Если по какой-то причине вы не можете использовать методы Material Components (например, работаете с кастомным View, который наследуется от VisibilityAwareImageButton), можно обойти ограничение библиотечных групп с помощью рефлексии. Однако это не рекомендуется для production-кода, так как нарушает архитектуру библиотеки и может привести к нестабильности.
fun setVisibilitySafely(view: View, visibility: Int) {
try {
val method = View::class.java.getMethod("setVisibility", Int::class.java)
method.isAccessible = true
method.invoke(view, visibility)
} catch (e: Exception) {
e.printStackTrace()
}
}
// Использование:
setVisibilitySafely(myButton, View.GONE)
Лучший вариант: Использовать View.animate()
Ещё один способ — анимировать изменение видимости через animate(), который также работает с системой библиотечных групп:
myButton.animate().alpha(0f).withEndAction {
myButton.visibility = View.GONE // теперь это сработает, так как вызывается из того же потока после анимации
}
Однако я настоятельно рекомендую придерживаться первого ответа — использовать публичные методы Material Components. Рефлексия и анимации — это лишь временные костыли, которые могут сломаться в будущих версиях библиотеки.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги