Защищенные поля не видны подклассам - PullRequest
15 голосов
/ 07 февраля 2011

Я пишу пользовательское представление, которое напрямую расширяет android.view.View.Если я пытаюсь получить доступ к полям mScrollX или mScrollY, я вижу ошибку, что поле «не может быть разрешено или не является полем».Исходный код для android.view.View имеет mScrollX, mScrollY и аналогичные переменные, объявленные protected.Как мой прямой подкласс не может получить доступ к защищенным полям своего родительского класса?(Классы вроде ScrollView , очевидно, могут.)

PS Я понимаю, что могу звонить getScrollX(), но я хочу обновить эти поля;У звонка setScroll() есть побочные эффекты, которые я не хочу.

Ответы [ 3 ]

21 голосов
/ 07 февраля 2011

Это потому, что они не являются частью 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, не будет включать этот элемент данных в версию-заглушку android.view.View, которая находится в файле android.jar, с которым вы компилируете.

Аннотация @hide используется для вещей, которые для внутренних целей должны быть публичными или защищенными, но не считаются чем-то, что разработчики SDK должны использовать.

Пожалуйста, найдите другие решения для любой проблемы, с которой вы столкнулись.

5 голосов
/ 07 февраля 2011

Это очень просто: обратите внимание на аннотацию @hide над этими переменными.Это специфичная для Android аннотация, которая скрывает поля / методы от общедоступного SDK.Вот почему вы не можете получить к ним доступ напрямую.

Romain Guy упомянул об этом в этой записи.

4 голосов
/ 22 февраля 2012

Вы можете попытаться установить поля с отражением:

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.
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...