У меня есть класс 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;
}
Любая помощь приветствуется. Спасибо!
x = (canvas.getWidth()/2) - (width/2);
y = (canvas.getHeight()/2) - (height/2);
. попробуйте также переместить все ваши инициализации и вычисления за пределыonDraw
.invalidate
нарисует проблема может быть в вашемonDraw
. - person Raghunandan   schedule 20.07.2013onDraw
вообще не вызывается, поэтому он никогда не приближается к этим инициализациям. Любая идея, почему это происходит? Спасибо! - person Rookatu   schedule 20.07.2013onDraw
называется. это что-то делать с вашей ничьей. Запишите некоторую информацию, напримерLog.i("Drawing","on draw called")
; - person Raghunandan   schedule 20.07.2013Log.d(TAG,"in onDraw method");
сразу после вызоваsuper.onDraw(canvas)
, и сообщение об отладке не печатается. - person Rookatu   schedule 20.07.2013onDraw
, а не в конструктор. если вы не видите, то ваше представление не вызывается. показывает нам, где вы используете свой собственный класс представления или вызываете конструктор. - person Raghunandan   schedule 20.07.2013super.onDraw(canvas)
, я отредактировал свой комментарий. Это вonDraw
, вот откуда я знаю, чтоonDraw
не звонят. Однако я могу убедиться, что доступ к другим методам в представлении осуществляется, например к методуsetHealth(...)
. Я отредактирую пост, чтобы показать, как определяется и вызывается представление. спасибо за помощь кстати - person Rookatu   schedule 20.07.2013getView
и проверьте - person Raghunandan   schedule 20.07.2013setImageBitmap(...)
должен автоматически вызыватьinvalidate()
, который вызываетonDraw(...)
. Однако я попытался вызватьinvalidate()
вручную, и нет, он по-прежнему не вызывает методonDraw(...)
. - person Rookatu   schedule 21.07.2013