Custom View embed in Gallery crashes while key press

Posted by tao on Stack Overflow See other posts from Stack Overflow or by tao
Published on 2010-03-18T07:48:33Z Indexed on 2010/03/18 7:51 UTC
Read the original article Hit count: 402

Filed under:

Hi there,

I'd like to find some stuff to replace the Tab component, so I'd make a custom View named StringView, which has the ability to display text, and to embed it into a Gallery. But it always crashes with error "NullPointerException at InputMethodManager".

I have no idea about this, any help&tip&suggest are appreciate.

Detail of my issue:

First

I'd created a class StringView extends View:

public class StringView extends View {
protected final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
protected String mString;
protected int mAscent;

// Constructor
public StringView(Context context, String string) {
    super(context);

    mPaint.setARGB(255, 255, 60, 10);
    mPaint.setTextSize(30);
    //mPaint.setFakeBoldText(true); 
    mString = string;
    setPadding(20,15,20,15);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    int w = this.getPaddingLeft();
    int h = this.getPaddingTop() - mAscent;
    canvas.drawText(mString, w, h, mPaint);
}

public void setString(String str) {
    mString = str;
    this.requestLayout();
    this.invalidate();
}
public String getString() {
    return mString;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(measureWidth(widthMeasureSpec),
                         measureHeight(heightMeasureSpec));
}

/**
 * Determines the width of this view
 * @param measureSpec A measureSpec packed into an int
 * @return The width of the view, honoring constraints from measureSpec
 */
private int measureWidth(int measureSpec) {
    int result = 0;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    if (specMode == MeasureSpec.EXACTLY) {
        // We were told how big to be
        result = specSize;                                                                                                                                
    } else {
        // Measure the text
        result = (int) mPaint.measureText(mString) + getPaddingLeft()
                + getPaddingRight();
        if (specMode == MeasureSpec.AT_MOST) {
            // Respect AT_MOST value if that was what is called for by measureSpec
            result = Math.min(result, specSize);
        }
    }

    return result;
}

/**
 * Determines the height of this view
 * @param measureSpec A measureSpec packed into an int
 * @return The height of the view, honoring constraints from measureSpec                                                                                  
 */
private int measureHeight(int measureSpec) {
    int result = 0;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    mAscent = (int) mPaint.ascent();
    if (specMode == MeasureSpec.EXACTLY) {
        // We were told how big to be
        result = specSize;
    } else {
        // Measure the text (beware: ascent is a negative number)
        result = (int) (-mAscent + mPaint.descent()) + getPaddingTop()
                + getPaddingBottom();
        if (specMode == MeasureSpec.AT_MOST) {
            // Respect AT_MOST value if that was what is called for by measureSpec
            result = Math.min(result, specSize);
        }
    }
    return result;
}

}

Second

I put it in to Gallery through Adapter

    Gallery gallery = (Gallery) findViewById(R.id.gallery);
    gallery.setAdapter(new ImageAdapter(this));

ImageAdapter:

public class ImageAdapter extends BaseAdapter {
    int mGalleryItemBackground;
    private Context mContext;
    private View[] mImages = genSerielImageViews();

    public ImageAdapter(Context c) {
        mContext = c;
        TypedArray a = obtainStyledAttributes(R.styleable.Gallery);
        mGalleryItemBackground = a.getResourceId(
                R.styleable.Gallery_android_galleryItemBackground, 0);
        a.recycle();
    }

    private View[] genSerielImageViews() {
        if (true) {
        int N = 6;
        StringView[] views = new StringView[N];
        for (int i=0; i<N; i++) {
            views[i] = new StringView(mContext, "ITEM #" + 
                                      Integer.toString(i) );
        }
        return views;
        }
        else {
            int N = 6;
            TextView[] views = new TextView[N];
            for (int i=0; i<N; i++) {
                views[i] = new TextView( mContext );
                views[i].setText("CCTV #" + Integer.toString(i) );
            }
            return views;
        }   
    }

    public int getCount() {
        return mImages.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        return mImages[position];
    }
}

Then Compile&Run, press keypad RIGHT and I got a crash, It's turns out a weird InputMethodManager error:

03-18 07:22:33.568: ERROR/AndroidRuntime(958): Uncaught handler: thread main exiting due to uncaught exception 03-18 07:22:33.648: ERROR/AndroidRuntime(958): java.lang.NullPointerException 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at android.view.inputmethod.InputMethodManager.startInputInner(InputMethodManager.java:940) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at android.view.inputmethod.InputMethodManager.checkFocus(InputMethodManager.java:1114) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at android.view.ViewRoot.handleMessage(ViewRoot.java:1869) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at android.os.Handler.dispatchMessage(Handler.java:99) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at android.os.Looper.loop(Looper.java:123) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at android.app.ActivityThread.main(ActivityThread.java:4310) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at java.lang.reflect.Method.invokeNative(Native Method) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at java.lang.reflect.Method.invoke(Method.java:521) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 03-18 07:22:33.648: ERROR/AndroidRuntime(958): at dalvik.system.NativeStart.main(Native Method)

Thanks.

© Stack Overflow or respective owner

Related posts about android