Drawable and Android screen pixel density for fixed-size image

I'm going through a problem in an application here my related to this issue. See if you can help me:

In my case I have a ImageView showing a ruler, and then I need to show this rule in real size, where it does not need to grow or shrink as the screen size or density. Using as a basis my Moto G3, it works perfectly, but when testo other devices, it loses the actual size of a ruler because the image tries to fit the screen size.

The image of the ruler is in PNG and measures 3600px x 155px and has measured up to 30cm, it is within a LinearLayout orizontal. In my Moto G3 visible area it is in 10cm, a larger screen for example it should show a larger area of ​​the ruler (11 to 15cm for example), but it contunua only 10cm in the visual field of the screen, showing that it grows and shrinks as the display settings and density of the device.

Before I had a picture of RAGUA for each resource (xxhdpi, xhdpi, etc), so I decided to migrate it to the assets folder of Android, but still with the same problem.

Do you have a light on how to fix it?

Follows the code:

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        <ImageView
            android:id="@+id/rulerPolegada"
            android:layout_width="1780dp"
            android:layout_height="103dp"
            android:layout_marginTop="-10dp"
            android:layout_marginLeft="@dimen/left_ruler"
            />
        </RelativeLayout>
        </HorizontalScrollView>
    </LinearLayout>

And as I said, after I image for assets, I started to set it in java:

rulerPolegada = (ImageView) view.findViewById(R.id.rulerPolegada);
        rulerPolegada.setImageDrawable(Controller.getImageAssets(getActivity(), "ruler_polegada.png"));

Upvotes: 0

Views: 2436

Answers (3)

Jim
Jim

Reputation: 1147

I'm not sure if you get your answers correct because it appears that previous answers were not satisfied. I had once the same problem - I need this ImageView to have the same size on a plethora of devices without scaling. I solved my problem by providing defined value in dp for layout_width and layout_height

Upvotes: 1

Krzysztof Skrzynecki
Krzysztof Skrzynecki

Reputation: 2525

Due to Understanding Density Independence In Android, you can calculate those values as follows

this table

Here is how you can calculate for your device (Moto G3)

  1. 30cm = 11.811 in
  2. Moto G3 screen density bucket is xhdpi - 320dpi
  3. 320px ~= 1 in
  4. 320px * 11.811in ~= 3780px

With this steps you can calculate how big your image should be.

Now, instead of providing different ruler's images for different screen densities, place your high quality image in drawable-anydpi folder, because A drawable in res/drawable-anydpi/ also is valid for any screen density. However, in this case, the -anydpi variant trumps any density-specific variant. due to '-nodpi, -anydpi, and WTF?' article from The CommonsBlog

Unfortunatelly, you can't used calculated values in layout xml file directly - ImageView size needs to be changed dynamically in Java code.

Above solution should give you decent accurancy (it can be diffent by 10%), but you can use DensityMetrics together with default display to get actual horizontal and vertical density, which will help you calculate image pixel size more precisely.

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);

// these will return the actual dpi horizontally and vertically
float xDpi = dm.xdpi;
float yDpi = dm.ydpi;

Edit

Calculation for 480dp:

  1. 30cm = 11.811 in
  2. density bucket xxhdpi - 480dp
  3. 480px ~= 1in
  4. 480px * 11.811in ~= 5669px

Upvotes: 1

wanz
wanz

Reputation: 299

You should read this guide for run in multiscreen

Upvotes: 0

Related Questions