具有自定义View的NullPointerException

时间:2012-06-25 16:59:53

标签: android

首先抱歉我的英语,我是西班牙语,现在,我在制作一个扩展View的自定义类时遇到了问题。 Theese是我的类和我的xml文件:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="@android:color/white" >

        <ImageButton
            android:id="@+id/paleta"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/paleta" />
    </LinearLayout>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pizarra"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >


    </LinearLayout>

</LinearLayout>

public class Pintar extends View {
    private Bitmap mBitmap = null;
    private Canvas mCanvas = null;
    private Path mPath = null;
    private float mX, mY;
    private static final float TOLERANCE = 4;
    private LinearLayout pizarra;

    public Pintar(Context context) {
        super(context);
        // obtener pantalla
        pizarra= (LinearLayout) findViewById (R.id.pizarra);
        mBitmap = Bitmap.createBitmap(pizarra.getWidth(),
                pizarra.getHeight(), Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
        mPath = new Path();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touchStart(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            touchMove(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touchUp();
            invalidate();
            break;
        }
        return true;
    }

    private void touchStart(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }

    private void touchMove(float x, float y) {
        if (Math.abs(x - mX) >= TOLERANCE || Math.abs(y - mY) >= TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
        }
    }

    private void touchUp() {
        mPath.lineTo(mX, mY);
        mCanvas.drawPath(mPath, Blackboard.mPaint);
        mPath.reset();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // fondo
        canvas.drawColor(0XFFBBBBBB);
        // lo ya pintado
        canvas.drawBitmap(mBitmap, 0, 0, null);
        // el trazo actual
        canvas.drawPath(mPath, Blackboard.mPaint);
    }



public class Blackboard extends Activity {

    public static Paint mPaint = null;
    protected Pintar board;
    private LinearLayout pizarra;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        board = new Pintar(this);
        pizarra= (LinearLayout) findViewById (R.id.pizarra);
        pizarra.addView(board);
        setContentView(R.layout.main);
        // preparamos el pincel
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(0XFF00E1FF);
        mPaint.setStrokeWidth(10);
    }

我想在顶部的LinearLayout中显示一个ImageButton,在底部的LinearLayout中我想用我的自定义类绘制但是我有这个错误:

06-25 18:43:07.578: E/AndroidRuntime(19822): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.acme.blackboard/com.acme.blackboard.Blackboard}: java.lang.NullPointerException

感谢答案

3 个答案:

答案 0 :(得分:0)

您的自定义视图Pintar从不放置任何内容,因此找不到findViewById将始终返回null。解决问题的一种简单方法是从FrameLayout(或其他ViewGroup)派生而来:

public class Pintar extends FrameLayout {

public Pintar(Context context) {
    super(context);

    final LayoutInflater layoutInflater = LayoutInflater.from(context);
    layoutInflater.inflate(R.layout.whatever_your_layout_id_is, this, true);

    pizarra= (LinearLayout) findViewById (R.id.pizarra); // << now this will have something to find
    ...

答案 1 :(得分:0)

findViewbyId代码移至setContentView来电后的行

public class Blackboard extends Activity {
...

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    board = new Pintar(this);
    pizarra= (LinearLayout) findViewById (R.id.pizarra);
    pizarra.addView(board);

    // preparamos el pincel
    mPaint = new Paint();
    mPaint.setStyle(Paint.Style.STROKE);
    ....
    ....
}

答案 2 :(得分:0)

在访问之前,您需要在HTML中包含自定义视图:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="@android:color/white" >

        <ImageButton
            android:id="@+id/paleta"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/paleta" />
    </LinearLayout>

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pizarra"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

       <com.yourpackage.Pintar android:id="@+id/pintar" ... />

   </LinearLayout>

</LinearLayout>

然后在您的代码中,您只需findViewById而不是创建新实例:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    board = (Pintar)this.findViewById(R.id.pintar);
    pizarra= (LinearLayout) findViewById (R.id.pizarra);

    ...
}