As @biegleux mentioned in his answer, initializeScrollbars()
is now annotated with @removed
in the API 21 source code. Here is the method source from 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();
}
Based on the comment in the method, it sounds like the issue before API 21 was that it was not safe to pass in a TypedArray
, but now it no longer uses the passed in TypedArray
. So it seems like this should be annotated with @Deprecated
instead of @removed
and there should be a new version of this method that takes no parameter that can be called when we need to initialize the scrollbars from a custom view that's created programmatically.
Until this gets fixed, there's two ways you can work around the issue:
1) Inflate your custom view from xml with the android:scrollbars
attribute set. This is the safest method and should work with all past and future platform versions. For example:
Create an xml layout file (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"/>
Inflate your custom view:
MyCustomView view = (MyCustomView) LayoutInflater.from(context).inflate(R.layout.my_custom_view, container, false);
2) Use reflection to invoke initializeScrollbars()
in your custom view's constructor. This could fail in future API versions if the method initializeScrollbars()
is actually removed or renamed. For example:
In your custom view (e.g. 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();
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…