Защищенные поля, не видимые для подклассов

Я пишу пользовательское представление, которое напрямую расширяет 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.
}

Обратите внимание, однако, что вы полагаетесь на недокументированное и неподдерживаемое поведение, когда вы это делаете, и поэтому вы должны быть готовы к тому, чтобы что-то ломалось на некоторых устройствах или в будущих версиях.