1

我有一个扩展的自定义控件RelativeLayout。里面我有一个ImageButton和一个TextView。这是代码的一部分:

    public CustomImageButton(Context context) {
            super(context);
            ((Activity)getContext()).getLayoutInflater().inflate(R.layout.custom_image_button, this);
            this.setClickable(false);
            setupViewItems();
        }

        public CustomImageButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            ((Activity)getContext()).getLayoutInflater().inflate(R.layout.custom_image_button, this);
            this.setClickable(false);
            TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CustomImageButton);
            setAttributes(attributes);
            setupViewItems();
            attributes.recycle();
        }
    private void setupViewItems() {
            final ImageButton imageButton = (ImageButton) findViewById(R.id.image_button);
            final TextView textView = (TextView) findViewById(R.id.text_view);


            final String text = this.text;
            final int paddingTopPercentage = this.textTopPadding;
            final int textAlignment = this.textAlignment;

            textView.setText(text);
            textView.setTextSize(this.textSize);
            textView.setTextColor(this.textColor);

            ViewTreeObserver vto = imageButton.getViewTreeObserver();
            vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                public boolean onPreDraw() {
                    int imageHeight = imageButton.getMeasuredHeight();
                    int imageWidth = imageButton.getMeasuredWidth();

                    boolean isTextInCorrectSize = true;
                    int textWidth = 0;
                    do {

                        if (!isTextInCorrectSize)
                            textView.setTextSize(textView.getTextSize() - 1f);

                        Rect bounds = new Rect();
                        Paint textPaint = textView.getPaint();
// BUG HERE - I GET A NULL POINTER EXCEPTION WHEN RUNNING getTextBounds function
                        textPaint.getTextBounds(text, 0, text.length(), bounds);
                        //int textHeight = bounds.height();
                        textWidth = bounds.width();
                        isTextInCorrectSize = (imageWidth - textWidth) > 0; 

                    }while(!isTextInCorrectSize);

                    //DOING SOME STUFF HERE
                    return true;
                }
            });
        }

我不知道它是否相关,但是在应用程序的某些部分中,此控件直接添加到布局 xml 中,有时我需要以编程方式添加组件(因此有 2 个不同的构造函数)。如果自定义组件是通过布局 xml 添加的 - 那么我没有任何问题,但是当我通过代码添加自定义组件时,我在执行 getTextBounds 函数时得到 NullPointerException(参见上面的代码)。当我调试和评估所有参数和调用该函数的 textView 时 - 没有什么是空的。关于为什么以及如何克服这个问题的任何想法?
谢谢


编辑:这是堆栈跟踪:

'java.lang.NullPointerException' with message 'null'. Stack trace:
        com.company.product.ui.views.CustomImageButton$1.onPreDraw(CustomImageButton.java:155)
        android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:571)
        android.view.ViewRoot.performTraversals(ViewRoot.java:1259)
        android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
        android.os.Handler.dispatchMessage(Handler.java:99)
        android.os.Looper.loop(Looper.java:123)
        android.app.ActivityThread.main(ActivityThread.java:3687)
        java.lang.reflect.Method.invokeNative(Native Method)
        java.lang.reflect.Method.invoke(Method.java:507)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
        dalvik.system.NativeStart.main(Native Method)

    *****************
    ****** GMT Time: 17 Feb 2013 13:09:36 GMT
    ****** Application name: AppName
    ****** User agent: (Android 2.3.3)
    ******************************
    ****** Exception type: java.lang.NullPointerException
    ****** Exception message: null
    ****** Trace trace:
        com.company.product.ui.views.CustomImageButton$1.onPreDraw(CustomImageButton.java:155)
        android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:571)
        android.view.ViewRoot.performTraversals(ViewRoot.java:1259)
        android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
        android.os.Handler.dispatchMessage(Handler.java:99)
        android.os.Looper.loop(Looper.java:123)
        android.app.ActivityThread.main(ActivityThread.java:3687)
        java.lang.reflect.Method.invokeNative(Native Method)
        java.lang.reflect.Method.invoke(Method.java:507)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
        dalvik.system.NativeStart.main(Native Method)
4

1 回答 1

0

问题在于您在类的构造函数(您调用setupViewItems())中检索 TextView 的大小(边界),这是您无法做到的,因为 Android 尚未绘制它并因此确定了大小。相反,您必须通过覆盖View.onSizeChanged()方法来调整/检索视图项的大小 。即使是第一次调整 View 的大小,Android 也会调用此方法。

于 2013-02-17T13:39:30.263 回答