Метод onDraw() для дочернего класса ImageView не вызывается

У меня есть класс LayeredImageView, расширяющий ImageView, который я использую для создания растровых изображений, состоящих из слоев растровых изображений, нарисованных друг над другом. Растровые изображения, которые я рисую, — это военные юниты для игры, и одно из растровых изображений, которые я хотел бы наложить на растровое изображение юнитов, — это их здоровье. Я включаю переменную здоровья в методе onDraw() и рисую соответствующий Bitmap.

Моя проблема в том, что метод onDraw() никогда не вызывается (проверено с помощью отладочных сообщений).

Я держу адаптер своих LayeredImageViews в классе ImageViewAdapter, расширяющем BaseAdapter, и в вызове метода getView(...) imageView.setImageBitmap(mThumbIds[position]) с соответствующим аргументом Bitmap. Насколько я понимаю, это должен быть вызов метода invalidate() для LayeredImageView, который, в свою очередь, должен вызвать onDraw(), но, как я уже сказал, этого не происходит.

Вот ядро ​​класса LayeredImageView:

public class LayeredImageView extends ImageView{

private static final String TAG = "LayeredImageView";

Context mContext;
int health;

public LayeredImageView(Context context) {
    super(context);
    mContext = context;
    health = 0;
    setWillNotDraw(false);
}

public void setHealth(int health){
    this.health = health;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Bitmap healthIcon = null;
    int width;
    int height;
    int x;
    int y;

    switch(health){
    case 1:
        healthIcon = decodeSampledBitmapFromResource(mContext.getResources(),R.drawable.health1, 100, 100);
        break;
    case 2:
        healthIcon = decodeSampledBitmapFromResource(mContext.getResources(),R.drawable.health2, 100, 100);
        break;
    }
    if(healthIcon != null){
        width = healthIcon.getWidth();
        height = healthIcon.getHeight();
        x = canvas.getWidth() - width;
        y = canvas.getHeight() - height;
        canvas.drawBitmap(healthIcon, x, y, new Paint());
    }
}

public static int calculateInSampleSize(BitmapFactory.Options options,
        int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and
        // width
        final int heightRatio = Math.round((float) height
                / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will
        // guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}

public static Bitmap decodeSampledBitmapFromResource(Resources res,
        int resId, int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth,
            reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

}

Как видите, я безуспешно пытался реализовать предложение здесь.

ИЗМЕНИТЬ

Здесь создается экземпляр объекта LayeredImageView:

public View getView(int position, View convertView, ViewGroup parent) {
    LayeredImageView imageView;
    if (convertView == null) {  // if it's not recycled, initialize some attributes
        imageView = new LayeredImageView(mContext);
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(7, 5, 7, 5);
    }
    else{
        imageView = (LayeredImageView) convertView;
    }

    Piece piece = game.getPiece(position % 10, 9-position/10);
    if(piece != null){//here we overlay the health icon if the piece has non-zero health
        imageView.setHealth(piece.getHealth());
    }

    imageView.setImageBitmap(mThumbIds[position]);

    return imageView;
}

Любая помощь приветствуется. Спасибо!


person Rookatu    schedule 20.07.2013    source источник
comment
x = (canvas.getWidth()/2) - (width/2); y = (canvas.getHeight()/2) - (height/2);. попробуйте также переместить все ваши инициализации и вычисления за пределы onDraw. invalidate нарисует проблема может быть в вашем onDraw.   -  person Raghunandan    schedule 20.07.2013
comment
Проблема в том, что метод onDraw вообще не вызывается, поэтому он никогда не приближается к этим инициализациям. Любая идея, почему это происходит? Спасибо!   -  person Rookatu    schedule 20.07.2013
comment
@Rokatu регистрирует информацию о soem и проверяет, уверен ли я, что onDraw называется. это что-то делать с вашей ничьей. Запишите некоторую информацию, например Log.i("Drawing","on draw called");   -  person Raghunandan    schedule 20.07.2013
comment
Нет. Я помещаю строку Log.d(TAG,"in onDraw method"); сразу после вызова super.onDraw(canvas), и сообщение об отладке не печатается.   -  person Rookatu    schedule 20.07.2013
comment
поместите его в onDraw, а не в конструктор. если вы не видите, то ваше представление не вызывается. показывает нам, где вы используете свой собственный класс представления или вызываете конструктор.   -  person Raghunandan    schedule 20.07.2013
comment
Извините, я хотел позвонить super.onDraw(canvas), я отредактировал свой комментарий. Это в onDraw, вот откуда я знаю, что onDraw не звонят. Однако я могу убедиться, что доступ к другим методам в представлении осуществляется, например к методу setHealth(...). Я отредактирую пост, чтобы показать, как определяется и вызывается представление. спасибо за помощь кстати   -  person Rookatu    schedule 20.07.2013
comment
зарегистрируйте информацию, если еще getView и проверьте   -  person Raghunandan    schedule 20.07.2013
comment
Какую информацию мне распечатать? Я проверил простое сообщение отладки, и предложение if было доступно, но предложение else не было в моем коротком тесте. Я забыл, при каких условиях это было бы, хотя...   -  person Rookatu    schedule 20.07.2013
comment
Является ли представление недействительным где-то? Вызовите imageView.invalidate() в getView и посмотрите, не вызывается ли onDraw.   -  person spartygw    schedule 21.07.2013
comment
Ну, насколько я понял, setImageBitmap(...) должен автоматически вызывать invalidate(), который вызывает onDraw(...). Однако я попытался вызвать invalidate() вручную, и нет, он по-прежнему не вызывает метод onDraw(...).   -  person Rookatu    schedule 21.07.2013