I know these kinds of questions have been asked before, but I haven't seen one of this type yet. I am creating a custom android UI using android canvas. I have created all the necessary drawables for it and put them in the appropriate folders and I am now drawing the UI with this code:
public class MainMenuView extends View {
private Bitmap pasteImage;
private Bitmap adventureLetters;
private Bitmap settingsLetters;
private Bitmap quitLetters;
private Bitmap backgroundImage;
private DisplayMetrics metrics;
public MainMenuView(Context context){
super(context);
pasteImage = decodeFile(R.drawable.paste, 200, true);
Log.w("Visina imagea", String.valueOf(pasteImage.getHeight()));
pasteImage.recycle();
}
public MainMenuView(Context context, AttributeSet attrSet){
super(context, attrSet);
metrics = context.getResources().getDisplayMetrics();
pasteImage = decodeFile(R.drawable.paste, 330, true);
adventureLetters = decodeFile(R.drawable.adventureletters, 100, true);
settingsLetters = decodeFile(R.drawable.settingsletters, 100, true);
quitLetters = decodeFile(R.drawable.quitletters, 50, true);
Log.w("Je li image null? ", pasteImage == null ? "da" : "ne");
backgroundImage = decodeFileScaled(R.drawable.toothpastebackground);
backgroundImage = Bitmap.createScaledBitmap(backgroundImage, metrics.widthPixels - 20, metrics.heightPixels, true);
//adventureLetters = BitmapFactory.decodeResource(getResources(), R.drawable.adventureletters);
//settingsLetters = BitmapFactory.decodeResource(getResources(), R.drawable.settingsletters);
//quitLetters = BitmapFactory.decodeResource(getResources(), R.drawable.quitletters);
}
@Override
protected void onMeasure(int widthMeasure, int heightMeasure){
setMeasuredDimension(calculateMeasure(widthMeasure), calculateMeasure(heightMeasure));
Log.w(String.valueOf(calculateMeasure(widthMeasure)), "Izmjereno");
}
private static final int DEFAULT_SIZE = 70;
private int calculateMeasure(int measure) {
int result = (int)(DEFAULT_SIZE * getResources().getDisplayMetrics().density);
int specMode = MeasureSpec.getMode(measure);
int specSize = MeasureSpec.getSize(measure);
if(specMode == MeasureSpec.EXACTLY) result = specSize;
else if(specMode == MeasureSpec.AT_MOST){
result = Math.min(result, specSize);
}
return result;
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
if(canvas == null) Log.w("Canvas je null", "Da");
else Log.w("Canvas nije null", "ne");
Log.w("Usao u onDraw", "u onDraw sam sad");
canvas.save();
if(pasteImage == null) Log.w("Slika je null", "null slika");
canvas.drawBitmap(backgroundImage, 0, 0, null);
Log.w("Dimenzije slike sirina x visina bg", backgroundImage.getWidth() + " " + backgroundImage.getHeight());
canvas.drawBitmap(pasteImage, 110, 420, null);
canvas.drawBitmap(adventureLetters, 50, 60, null);
canvas.drawBitmap(settingsLetters, 80, 60, null);
canvas.drawBitmap(quitLetters, 100, 60, null);
pasteImage.recycle();
adventureLetters.recycle();
settingsLetters.recycle();
quitLetters.recycle();
canvas.restore();
}
private Bitmap decodeFile(int id, int size, boolean resize){
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), id, o);
//The new size we want to scale to
final int REQUIRED_SIZE = size;
//Find the correct scale value. It should be the power of 2.
int scale = 1;
while(o.outWidth/scale/2 >= REQUIRED_SIZE && o.outHeight/scale/2 >= REQUIRED_SIZE)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeResource(getResources(), id, o2);
}
private Bitmap decodeFileScaled(int id){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), id, options);
Log.w("Sirina x visina displaya", metrics.widthPixels + "x" + metrics.heightPixels);
options.inSampleSize = calculateScale(options, metrics.widthPixels, metrics.heightPixels);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(getResources(), id, options);
}
private int calculateScale(BitmapFactory.Options options, int reqWidth, int reqHeight){
final int rawHeight = options.outHeight;
final int rawWidth = options.outWidth;
int inSampleSize = 1;
if (rawHeight > reqHeight || rawWidth > reqWidth) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) rawHeight / (float) reqHeight);
final int widthRatio = Math.round((float) rawWidth / (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;
}
}
You can see immediately that I'm using some hardcoded values for positioning on screen. Can you give me some advice on how to code it so that it appears as it should on every screen(especially medium and high dimensions). As it should means no blurring tearing empty space and so on. If you need any more info let me know in the comments and thank you very much!