Проблема с рисованием растрового изображения на холсте

Я пытаюсь нарисовать изображение на холсте, и хотя программа успешно компилируется и ведет себя так, как я ожидаю, журнал ошибок показывает, что существует исключение NullPointerException, связанное с методом drawBitmap() ниже. Что странно, так это то, что мое изображение все еще нарисовано на холсте. В чем конкретно заключается проблема и как мне ее решить?

Мой код:

public class ProgressBar extends View
{
    String packageName;

    public ProgressBar(Context context)
    {
        super(context);
        packageName = context.getPackageName();
    }

    public ProgressBar(Context context, AttributeSet attribs)
    {
        super(context, attribs);
        packageName = context.getPackageName();
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);

        int resourceId = getResources().getIdentifier("bar1", "drawable", packageName);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
        canvas.drawBitmap(bitmap, 35, 35, null);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = View.MeasureSpec.getSize(widthMeasureSpec);
        mHeight = View.MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);
    }
}

Журнал ошибок:

java.lang.NullPointerException
at android.graphics.Canvas.throwIfRecycled(Canvas.java:1057)
at android.graphics.Canvas.drawBitmap(Canvas.java:1097)
at com.myapp.ProgressBar.onDraw(ProgressBar.java:50)
at android.view.View.draw(View.java:13944)
at android.view.View.draw(View.java:13825)
at android.view.ViewGroup.drawChild(ViewGroup.java:3083)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2920)
at android.view.View.draw(View.java:13823)
at android.view.ViewGroup.drawChild(ViewGroup.java:3083)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2920)
at android.view.View.draw(View.java:13823)
at android.view.ViewGroup.drawChild(ViewGroup.java:3083)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2920)
at android.view.View.draw(View.java:13823)
at android.view.ViewGroup.drawChild(ViewGroup.java:3083)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2920)
at android.view.View.draw(View.java:13947)
at android.view.View.draw(View.java:13825)
at android.view.ViewGroup.drawChild(ViewGroup.java:3083)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2920)
at android.view.View.draw(View.java:13947)

1 ответ

Вы никогда не должны извлекать растровое изображение из ресурсов в onDraw, потому что onDraw вызывается много раз в секунду, поэтому у него не будет времени для декодирования этого ресурса каждый раз, когда вызывается onDraw.

Вы должны декодировать ваше растровое изображение в своем конструкторе, сохранить его в переменной класса и использовать в onDraw.

В общем, все, что вам нужно сделать, это:

//add bitmap to class variable
private Bitmap bitmap;

//move these to constructor
int resourceId = getResources().getIdentifier("bar1", "drawable", packageName);
bitmap = BitmapFactory.decodeResource(getResources(), resourceId);

И все должно работать.

Другие вопросы по тегам