initializeScrollbars未定义?

and*_*per 9 android android-5.0-lollipop

背景

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

    final TypedArray a = context.obtainStyledAttributes(R.styleable.View);
    initializeScrollbars(a);
    a.recycle();
Run Code Online (Sandbox Code Playgroud)

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

问题

自从我更新了所有内容后,我不断收到此错误:

对于PLA_AbsListView类型,未定义方法initializeScrollbars(TypedArray)

我试过的

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

我也试图找出声明这个函数的位置.它应该是"View.java"中受保护的函数,但由于某种原因,我在文档中看不到它

这个问题

怎么会这样?

我该如何解决?

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

以前,当针对Kitkat时它起作用了......

bie*_*eux 7

来自View.javaandroid-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) {
Run Code Online (Sandbox Code Playgroud)

您没有看到它,因为该方法已注释@removed.initializeScrollbarsInternal()也不能用它注释@hide.从评论开始,使用此方法并不安全,您应该将其报告给lib的作者.


ash*_*hes 7

正如@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();
}
Run Code Online (Sandbox Code Playgroud)

基于该方法中的注释,听起来像API 21之前的问题是传入a是不安全的TypedArray,但现在它不再使用传入的TypedArray.所以看起来这应该被注释@Deprecated而不是@removed并且应该有这个方法的新版本,当我们需要从以编程方式创建的自定义视图初始化滚动条时,不会调用任何参数.

在此问题得到解决之前,您可以通过两种方法解决此问题:

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

创建一个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"/>
Run Code Online (Sandbox Code Playgroud)

膨胀您的自定义视图:

MyCustomView view = (MyCustomView) LayoutInflater.from(context).inflate(R.layout.my_custom_view, container, false);
Run Code Online (Sandbox Code Playgroud)

2)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();
}
Run Code Online (Sandbox Code Playgroud)