Защищенные поля, не видимые для подклассов
Я пишу пользовательское представление, которое напрямую расширяет android.view.View
. Если я попытаюсь получить доступ к полям mScrollX
или mScrollY
, я вижу ошибку, которую поле "не может быть разрешено или не является полем". Исходный код для android.view.View имеет mScrollX, mScrollY и аналогичные переменные, объявленные protected
. Как мой прямой подкласс не может получить доступ к защищенным полям своего родительского класса? (Классы типа ScrollView, по-видимому, могут.)
P.S. Я понимаю, что я могу назвать getScrollX()
, но я хочу обновить эти поля; вызов setScroll()
имеет побочные эффекты, которые я не хочу.
Ответы
Ответ 1
Это потому, что они не являются частью Android SDK.
Вот исходный код для mScrollX
:
/**
* The offset, in pixels, by which the content of this view is scrolled
* horizontally.
* {@hide}
*/
@ViewDebug.ExportedProperty(category = "scrolling")
protected int mScrollX;
Вы заметите аннотацию @hide
. Это означает, что это не часть Android SDK. Часть процесса сборки, которая создает Android SDK, не будет включать этот член данных в выпуске stub android.view.View
, который находится в файле android.jar
, который вы компилируете.
Аннотация @hide
используется для вещей, которые для внутренних целей должны быть общедоступными или защищенными, но не считаются разработчиками SDK, которые должны использовать.
Пожалуйста, найдите другие решения для любой проблемы, с которой вы столкнулись.
Ответ 2
Это очень прямолинейно: обратите внимание на аннотацию @hide над этими переменными.
Это аннотация для Android, которая скрывает поля/методы из общедоступного SDK. Вот почему вы не можете получить к ним доступ напрямую.
Ромен Гай упомянул об этом в этом сообщении.
Ответ 3
Вы можете попробовать установить поля с отражением:
import java.lang.reflect.Field;
// ...
try {
Field scrollXField = View.class.getDeclaredField("mScrollX");
scrollXField.setAccessible(true);
scrollXField.set(this, myNewValue);
} catch (Exception ex) {
// oops, android changed the implementation. sucks to be you.
}
Обратите внимание, однако, что вы полагаетесь на недокументированное и неподдерживаемое поведение, когда вы это делаете, и поэтому вы должны быть готовы к тому, чтобы что-то ломалось на некоторых устройствах или в будущих версиях.