Android Question ImageViews same size in different devices

GiovanniO

Member
Hi everyone. I have a question. I need to load some images into ImageViews to create image overlays. The problem arises when working with different devices. Even if I assign values to the ImageViews in %x and %y or in DIP, when I switch devices, the ImageViews don't remain in the same position or aren't the correct size (especially the ratio). Has anyone worked with this issue? I appreciate any help.

Gretings.
 

Sagenut

Expert
Licensed User
Longtime User
Please post an example project that show the issue to test.
In this way it will be possible to check what you are doing and eventually correct or explain the issue.
 
Upvote 0

GiovanniO

Member
Thank you for your answers.

@Sagenut , It's something as simple as a panel and two imageviews, the panel is at 100% (I want to do a "screenshoot" of the panel), i use this code in the designer:

B4X:
pBase.Width = 100%x
pBase.Height = 100%y

iv1.Width = 220dip  '61.3%x
iv1.Height = 220dip   '30.4%y
iv2.Height = iv1.Height
iv2.Width = iv1.Width

iv1.Left = 15dip
iv1.Top = 240dip

iv2.Left = 120dip
iv2.Top = 360dip

pMask.Width = 100%x
pMask.Height = 100%y

@LucaMs i don't have AutoScallAll and i put the ImageViews in dip, however, depending on the device, the ImageView becomes wider, so it doesn't maintain the image's proportions within it. Worse, I want to put a background image in the base panel, and I'd like to align the ImageViews so that when the screenshot is taken, the entire contents appear as a single image.

Thanks again for your help.
 
Upvote 1

BlueVision

Well-Known Member
Licensed User
Longtime User
I think your problem is created by different form factors of the devices.
Very old smartphones tend to use old tv ratio of 4:3, newer using 16:9, nowadays it tends more and more to 2:1.
So your value of X% is never the same like Y% from the point of a given distance on the screen.
The more the length of displays increases, the more increases the value of 1%y compared to 1%x.
So if you want to draw a square and not a rectangle, using percentages is more or less following the form factor of the display or it's screen ratio. It will not work only with the percentages.
I personally don't like using dips, because this fails in another way. Imagine you want to move an object by shifting in absolute dips behind another object. This may work on one device, but also not on a second device. Never figured out how this is done perfectly.

But how are you able to solve this problem, especially if you do not know the screen ratio on the final device?
(believe me, it will drive you nuts when trying to draw a circle on several devices)

When using the designer, you have to calculate the ratio for the designer script (ratio = 100%x / 100%y). With this value ratio you are able to draw an exact square on multiple devices independing their form factor. It's all about defining the x-axis or y-axis of that object with a given value depending surrounding objects und calculating the other axis with the value of ratio and centering it correctly based on it's final size within the given view.

The two pictures below demonstrate a little bit better what I try to explain. Watch the different form factors of the devices and then the circle of the compass rose.
This is the way I solve that problem. Sure, depending on the limits of the given space, the compass rose will "pump" with this procedure. A circle is a circle...

1.jpg 2.jpg
 
Upvote 0

Sagenut

Expert
Licensed User
Longtime User
@GiovanniO
Are you saying that on different screen the Imageview become rectangular instead that square?
Eventually try this
B4X:
pBase.Width = 100%x
pBase.Height = 100%y

iv1.Width = 220dip  '61.3%x
iv1.Height = iv1.Width
iv2.Height = iv1.Width
iv2.Width = iv1.Width

iv1.Left = 15dip
iv1.Top = 240dip

iv2.Left = 120dip
iv2.Top = 360dip

pMask.Width = 100%x
pMask.Height = 100%y
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Thank you for your answers.

@Sagenut , It's something as simple as a panel and two imageviews, the panel is at 100% (I want to do a "screenshoot" of the panel), i use this code in the designer:

B4X:
pBase.Width = 100%x
pBase.Height = 100%y

iv1.Width = 220dip  '61.3%x
iv1.Height = 220dip   '30.4%y
iv2.Height = iv1.Height
iv2.Width = iv1.Width

iv1.Left = 15dip
iv1.Top = 240dip

iv2.Left = 120dip
iv2.Top = 360dip

pMask.Width = 100%x
pMask.Height = 100%y

@LucaMs i don't have AutoScallAll and i put the ImageViews in dip, however, depending on the device, the ImageView becomes wider, so it doesn't maintain the image's proportions within it. Worse, I want to put a background image in the base panel, and I'd like to align the ImageViews so that when the screenshot is taken, the entire contents appear as a single image.

Thanks again for your help.
Using that code should ensure that the size and position of the two ImageViews remain fixed on any display.

Perhaps your real problem is the displayed images; if they don't have the same width/height ratio as the ImageViews, they'll obviously be displayed distorted.
 
Upvote 0

GiovanniO

Member
I think your problem is created by different form factors of the devices.
Very old smartphones tend to use old tv ratio of 4:3, newer using 16:9, nowadays it tends more and more to 2:1.
So your value of X% is never the same like Y% from the point of a given distance on the screen.
The more the length of displays increases, the more increases the value of 1%y compared to 1%x.
So if you want to draw a square and not a rectangle, using percentages is more or less following the form factor of the display or it's screen ratio. It will not work only with the percentages.
I personally don't like using dips, because this fails in another way. Imagine you want to move an object by shifting in absolute dips behind another object. This may work on one device, but also not on a second device. Never figured out how this is done perfectly.

But how are you able to solve this problem, especially if you do not know the screen ratio on the final device?
(believe me, it will drive you nuts when trying to draw a circle on several devices)

When using the designer, you have to calculate the ratio for the designer script (ratio = 100%x / 100%y). With this value ratio you are able to draw an exact square on multiple devices independing their form factor. It's all about defining the x-axis or y-axis of that object with a given value depending surrounding objects und calculating the other axis with the value of ratio and centering it correctly based on it's final size within the given view.

The two pictures below demonstrate a little bit better what I try to explain. Watch the different form factors of the devices and then the circle of the compass rose.
This is the way I solve that problem. Sure, depending on the limits of the given space, the compass rose will "pump" with this procedure. A circle is a circle...

View attachment 168002 View attachment 168001
First of all, thank you for your kind reply. I'm bad at math; once I've calculated the ratio, how do I apply it to the views?

@Sagenut , Thanks for your reply. That solves my perfect square problem (thanks!).

@LucaMs ,
I don't think I explained myself perfectly. What I want to do is technically something like this:

We have a panel with a background image (we're starting with the problem of distortions on different devices, since the image will be distorted depending on the screen size). On this panel, we have two ImageViews: one square and one rectangular.

Let's imagine, for example, an image of a poker table (this isn't the case I'm working on, but it serves as an example). In that image, there are two white "marks" where the images need to fit. One mark is rectangular to hold a poker card, and the other is square to hold a die. Obviously, the rectangle will display a card, and depending on the user's selections, it will show one card or another, while the square ImageView will display the image of a die, also depending on the user's selection.

How can we fit the rectangular ImageView into its designated space and the square ImageView into its assigned space without losing the aspect ratio?

Ultimately, I want to do something like this: once the images are arranged in their correct positions and proportions, I want a screenshot of that panel to be taken and saved as an image.

PS: It's a photo app; I'm not involved in gambling or games of chance, hahaha.

Regards, and thanks again for your help.
 
Upvote 0

BlueVision

Well-Known Member
Licensed User
Longtime User
First of all, thank you for your kind reply. I'm bad at math; once I've calculated the ratio, how do I apply it to the views?

Hi Giovanni,
sorry for the late reply. I am very busy at work.

Pls. follow this advice (the small sample project ist to large to put it here)

1. open a new B4xPages Project
2. you don't have to write some code for it, all is done within the designer script
3. open designer
4. add a panel to the activity named Panel1
5. add Label1 as a child to Panel1
6. Change the colour of Panel1 to Grey
7. Change the colour of Label1 to Red
8. put this code into the designer

Visual Designer Script for creating a square independent display size:
'All variants script
AutoScaleAll
Ratio = 100%x/100%y
Panel1.SetLeftAndRight(0%x,100%x)
Panel1.SetTopAndBottom(0%y,100%y)
Label1.SetLeftAndRight(Panel1.HorizontalCenter-30%x,Panel1.HorizontalCenter+30%x)
Label1.SetTopAndBottom(Panel1.VerticalCenter-30%y*Ratio,Panel1.VerticalCenter+30%y*Ratio)

It is very simple. Install this on all devices you own. You should see a red square on a gray background on every device.
I think the code explains enough what I do.

If you are using an imageview and not a label, it depends on the configuration of the imageview how the image is loaded. You should keep the ratios of the picture and you should not try to fill the imageview completely. Use loadbitmapsample for loading the picture into the imageview and keep aspect ratio of the picture.

Hope this will help you.
All is done with the designer script as you can see, no dips or anything else.

Sure, with this method the height follows the width always. So the label is "pumping" in size if you compare between the devices. But the label is always a square, never a rectangle. (hope so;))

Cheers from Berlin,
BV
 
Upvote 0
Top