initializeScrollbars是未定义的?

背景

我正在使用这个库 ,它的一个类(从ViewGroup扩展),在CTOR内部的“PLA_AbsListView.java”中,有这些行:

final TypedArray a = context.obtainStyledAttributes(R.styleable.View); initializeScrollbars(a); a.recycle(); 

最近,我更新了Android的SDK和ADT以支持新的Android版本(Lollipop – API21)。

问题

自从我更新了所有内容之后,我一直在收到这个错误:

对于typesPLA_AbsListView,方法initializeScrollbars(TypedArray)未定义

我试过了

我试图将API设置为低于21,但它没有帮助。

我也试图找出这个函数声明在哪里。 它应该是“View.java”中的一个受保护的函数,但由于某种原因,我无法在文档看到它

这个问题

怎么会这样?

我该如何解决?

这有可能是文档中的一个错误吗?

它以前工作,当瞄准奇巧…

Solutions Collecting From Web of "initializeScrollbars是未定义的?"

来自android-21源码的View.java

 /** * ... * * @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标注。 从评论中使用这种方法是不安全的,你一定要把它报告给lib的作者。

正如@biegleux在他的回答中提到的, initializeScrollbars()现在在API 21源代码中用@removed标注。 以下是来自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中的TypedArray 。 所以看起来应该使用@Deprecated而不是@removed来注释这个方法,并且应该有一个这个方法的新版本,当我们需要从程序创build的自定义视图中初始化滚动条的时候,这个方法不需要任何参数。

在这个问题得到解决之前,有两种方法可以解决这个问题:

1)使用android:scrollbars属性集从xml膨胀自定义视图。 这是最安全的方法,应该适用于所有过去和未来的平台版本。 例如:

创build一个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)使用reflection来调用你的自定义视图的构造函数中的initializeScrollbars() 。 如果方法initializeScrollbars()实际上被删除或重命名,这可能在未来的API版本中失败。 例如:

在你的自定义视图中(例如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(); }