initializeScrollbars не определен?
Фон
Я использую эту библиотеку, которая для одного из ее классов (который выходит из ViewGroup), в "PLA_AbsListView.java", внутри CTOR, есть такие строки:
final TypedArray a = context.obtainStyledAttributes(R.styleable.View);
initializeScrollbars(a);
a.recycle();
Недавно я обновил SDK & ADT Android для поддержки новой версии Android (Lollipop - API21) .
Эта проблема
С тех пор, как я обновил все, я получаю эту ошибку:
Метод initializeScrollbars(TypedArray) не определен для типа PLA_AbsListView
Что я пробовал
Я пытался установить API для использования ниже 21, но это не помогло.
Я также попытался выяснить, где объявлена эта функция. Предполагается, что это защищенная функция в "View.java", но по какой-то причине я не вижу ее в документации
Вопрос
Как это могло произойти?
Как я могу это исправить?
Возможно ли, что это ошибка в документации?
Это работало раньше, когда нацелился на Киткат...
2 ответа
От View.java
из android-21
источники:
/**
* ...
*
* @removed
*/
protected void initializeScrollbars(TypedArray a) {
// It's not safe to use this method from apps. The parameter 'a' must have been obtained
// using the View filter array which is not available to the SDK. As such, internal
// framework usage now uses initializeScrollbarsInternal and we grab a default
// TypedArray with the right filter instead here.
TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
initializeScrollbarsInternal(arr);
// We ignored the method parameter. Recycle the one we actually did use.
arr.recycle();
}
/**
* ...
*
* @hide
*/
protected void initializeScrollbarsInternal(TypedArray a) {
Вы не видите этого, потому что метод аннотирован @removed
, initializeScrollbarsInternal()
также не может быть использован, так как он помечен @hide
, Поскольку из комментария использовать этот метод небезопасно, вы обязательно должны сообщить об этом автору библиотеки.
Как сказал @biegleux в своем ответе, initializeScrollbars()
в настоящее время аннотируется @removed
в исходном коде API 21 Вот источник метода из API 21:
protected void initializeScrollbars(TypedArray a) {
// It's not safe to use this method from apps. The parameter 'a' must have been obtained
// using the View filter array which is not available to the SDK. As such, internal
// framework usage now uses initializeScrollbarsInternal and we grab a default
// TypedArray with the right filter instead here.
TypedArray arr = mContext.obtainStyledAttributes(com.android.internal.R.styleable.View);
initializeScrollbarsInternal(arr);
// We ignored the method parameter. Recycle the one we actually did use.
arr.recycle();
}
Судя по комментарию в методе, до API 21 проблема заключалась в том, что передавать в TypedArray
, но теперь он больше не использует переданный в TypedArray
, Похоже, это должно быть отмечено @Deprecated
вместо @removed
и должна быть новая версия этого метода, которая не принимает параметров, которые могут быть вызваны, когда нам нужно инициализировать полосы прокрутки из пользовательского представления, созданного программным способом.
Пока это не будет исправлено, есть два способа обойти эту проблему:
1) Раздуйте свой пользовательский вид из xml с помощью android:scrollbars
набор атрибутов. Это самый безопасный метод, который должен работать со всеми предыдущими и будущими версиями платформы. Например:
Создать файл макета XML (my_custom_view.xml
):
<com.example.MyCustomView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="horizontal|vertical"/>
Раздуйте свой пользовательский вид:
MyCustomView view = (MyCustomView) LayoutInflater.from(context).inflate(R.layout.my_custom_view, container, false);
2) Используйте отражение, чтобы вызвать initializeScrollbars()
в конструкторе вашего пользовательского представления. Это может привести к сбою в будущих версиях API, если метод initializeScrollbars()
фактически удален или переименован. Например:
В вашем собственном представлении (например, MyCustomView.java
):
public MyCustomView(Context context) {
super(context);
// Need to manually call initializedScrollbars() if instantiating view programmatically
final TypedArray a = context.getTheme().obtainStyledAttributes(new int[0]);
try {
// initializeScrollbars(TypedArray)
Method initializeScrollbars = android.view.View.class.getDeclaredMethod("initializeScrollbars", TypedArray.class);
initializeScrollbars.invoke(this, a);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
a.recycle();
}