Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
155 views
in Technique[技术] by (71.8m points)

android - initializeScrollbars is undefined?

Background

I'm using this library which for one of its classes (that extends from ViewGroup), in "PLA_AbsListView.java", inside the CTOR, there are those lines:

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

Recently, I've updated the SDK & ADT of Android to support the new Android version (Lollipop - API21) .

The problem

Ever since I've updated everything, I keep getting this error:

The method initializeScrollbars(TypedArray) is undefined for the type PLA_AbsListView

What I've tried

I've tried to set the API to be used as lower than 21, but it didn't help.

I've also tried to find out where this function is declared. It's supposed to be a protected function within "View.java", but for some reason, I can't see it in the documentations

The question

How could it be?

How can I fix it?

Is it possible it's a bug in the documentation?

It worked before, when targeting Kitkat...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...