开发者

Programmatically creating scrollview(s) from custom component in android

开发者 https://www.devze.com 2022-12-30 23:03 出处:网络
I\'m trying to build a compound control in Android, containing (among other things) a ScrollView. Things go wrong when I try to view the control in Eclipse, crashing with a NullPointerException after

I'm trying to build a compound control in Android, containing (among other things) a ScrollView. Things go wrong when I try to view the control in Eclipse, crashing with a NullPointerException after the error message: "Parser is not a BridgeXmlBlockParser".

Stacktrace:

java.lang.NullPointerException
at android.view.View.<init>(View.java:1720)
at android.view.ViewGroup.<init>(ViewGroup.java:277)
at android.widget.FrameLayout.<init>(FrameLayout.java:83)
at android.widget.ScrollView.<init>(ScrollView.java:128)
at android.widget.ScrollView.<init>(ScrollView.java:124)
at android.widget.ScrollView.<init>(ScrollView.java:120)
at m开发者_运维知识库y.compound.control.StringPicker.onMeasure(StringPicker.java:46)
...

I've traced the error to the following conditions:

  • The NPE is thrown because a Context.obtainStyledAttributes() call returns null when the attrs argument passed is null.
  • This only applies to the BridgeContext implementation used in Eclipse, which expects attrs to be an instance of the BridgeXmlBlockParser.
  • The attrs argument is null because I create the ScrollView using the (Context) constructor.

There is a workaround of course, which is passing the attrs I receive when Eclipse constructs the compound control, but I don't want all the attributes set on the compound control to apply to my inner control.

Am I doing something wrong, is this a bug in Android Eclipse, ...?

This is what my.compound.control.StringPicker.onMeasure looks like (stripped it a bit for clarity):

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (this.getChildCount() != requestedLength) {
        this.removeAllViews();
        int childWidth = getWidth() / requestedLength;
        int childHeight = getHeight();
        for (int i = 0; i < requestedLength; i++) {
            ScrollView child = new ScrollView(getContext()); // NPE here
            child.setLayoutParams(new LayoutParams(childWidth, childHeight));
            addView(child);
        }
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}


How are you creating your compound control, via XML layout or dynamically in the code? A possible reason I could think of is that you are adding it via XML but you may not have added the StringPicker(Context context, AttributeSet attrs) constructor. There you should call super(context, attrs).


It seems to have been a bug in older Android versions.

The problem does not appear in Android version 2.3 or higher, but does appear when selecting Android 2.2 or lower. The workaround for these older Android versions is (as mentioned in the question) to copy the attrs parameter from the constructor.
This is only needed if you want to use design-view in Eclipse with these older versions, to run your application in the older versions no workaround is necessary.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号