0

I am setting up images for different devices as per official google docs.As per google docs we should always use dp(density independent pixels) because pixels may varies for different devices. So i have managed images as per dp(density independent pixels). I have put images in drawable xhdpi,hdpi,mdpi and ldpi. it works well for most of devices but for different devices ppi pixels may varies from device to device so dp(density independent pixels) is not fixed so my all calculations according to dp(density independent pixels) goes wrong and cannot be set properly.

Let me explain me with example. here is my xml i am setting up :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_footer"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#FF0000"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/ft_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />

    <ImageView
        android:id="@+id/ft_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />

    <ImageView
        android:id="@+id/ft_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />

    <ImageView
        android:id="@+id/ft_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />

    <ImageView
        android:id="@+id/ft_5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />

    <ImageView
        android:id="@+id/ft_6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:src="@drawable/ico_test" />

</LinearLayout>

when i see this layout in Micromax canvas 4(294 ppi pixels) it seems perfect. but in Google Nexus 4(318 ppi pixels) it leaves more space from right side(you can see it in images i have attached.).

i tried to get following details

density :
dpHeight :
dpWidth :

using below java code :

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);

float density  = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth  = outMetrics.widthPixels / density;

i get following results for nexus 4 and canvas 4 :

(canvas 4)
density : 2.0
dpHeight : 640
dpWidth : 360

(nexus 4)
density : 2.0
dpHeight : 592
dpWidth : 384

as you can see here dp(density independent pixels) varies for these devices i think it is because of different ppi pixels so all my calculations according to dp(density independent pixels) goes wrong. so how can i manage images if dp is not fixed.??

i have also attached screen shot of the images how layout looks in canvas 4 and nexus 4.

I have also referred this question How do I convert ppi into dpi for Android images?

i know i can adjust layouts using the layout weight but i think there must be another solution to this problem.

Please see and help me to solve the problem.

Nexus 4 Screenshot Canvas 4 screenshot

Community
  • 1
  • 1
Nirav Tukadiya
  • 3,367
  • 1
  • 18
  • 36

7 Answers7

4

You just cannot support all the devices, Either you can create different layouts or different drawables to target each device.

The best thing you can do is make a flexible UI that divides the view in proportions and for doing this WEIGHT come into existence . Just use weight to divide the UI into proportion like this

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_footer"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#FF0000"
    android:orientation="horizontal" 
    android:weightSum="6">

    <ImageView
        android:layout_weight="1"
        android:id="@+id/ft_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:layout_weight="1"
        android:id="@+id/ft_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:layout_weight="1"
        android:id="@+id/ft_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:layout_weight="1"
        android:id="@+id/ft_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:layout_weight="1"
        android:id="@+id/ft_5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:layout_weight="1"
        android:id="@+id/ft_6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:src="@drawable/ic_launcher" />

</LinearLayout>
Jitender Dev
  • 6,907
  • 2
  • 24
  • 35
  • thanks for help i know i can do this using weights but i want to know how to manage it with devices with different ppi pixels without using weights.because i used to do it with dp without using layotu weights for devices but now dp varies from devices to devices based on ppi pixels. and that is my problem! – Nirav Tukadiya Oct 21 '13 at 09:53
  • You really should use weights for this. – Jeffrey Klardie Oct 30 '13 at 09:46
  • 1
    `dp varies from devices to devices based on ppi pixels. and that is my problem!` Define `weightSum` as an integer value and `layout_weight` also. Use these in your layout. Now, in xhdpi you may have a different value (let's say 6 for sum and 1 for each) ... For mdpi you may put a different value: maybe 10 and 1.6 for each - use adaptive resources based on device screen config. – gunar Oct 30 '13 at 13:33
1

Try this

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_footer"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#FF0000"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/ft_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="3dp"
        android:layout_weight="1"
        android:adjustViewBounds="true"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:id="@+id/ft_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="3dp"
        android:layout_weight="1"
        android:adjustViewBounds="true"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:id="@+id/ft_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="3dp"
        android:layout_weight="1"
        android:adjustViewBounds="true"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:id="@+id/ft_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="3dp"
        android:layout_weight="1"
        android:adjustViewBounds="true"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:id="@+id/ft_5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="3dp"
        android:layout_weight="1"
        android:adjustViewBounds="true"
        android:src="@drawable/ic_launcher" />

    <ImageView
        android:id="@+id/ft_6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="3dp"
        android:layout_weight="1"
        android:adjustViewBounds="true"
        android:src="@drawable/ic_launcher" />

</LinearLayout>
Biraj Zalavadia
  • 28,348
  • 10
  • 61
  • 77
  • thanks for help i know i can do this using weights but i want to know how to manage it with devices with different ppi pixels without using weights.because i used to do it with dp as dp was fixed for devices but now it is not.and that is my problem. – Nirav Tukadiya Oct 21 '13 at 09:49
1

I do in such a way

Display display = getWindowManager().getDefaultDisplay();
int screenWidth = display.getWidth()/6; //number of buttons
button.setLayoutParams(new LinearLayout.LayoutParams(screenWidth, android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
button2.setLayoutParams(new LinearLayout.LayoutParams(screenWidth, android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
....

make it as for each buttons in same way..

or

Tabbar concept works in anotherway..

arshad kr
  • 357
  • 3
  • 16
  • thanks for help but i can also do this using layout weights but i want to know how to manage it with devices with different ppi pixels.because i used to do it with dp as dp was fixed for devices but now it is not.and that is my problem. – Nirav Tukadiya Oct 21 '13 at 09:47
  • am sorry... am not getting what you mean but I used same snippet in my cases for different pix of devices and its worked.. anyhow good luck.. if you found any other way let me know. – arshad kr Oct 21 '13 at 10:18
  • ya sure.i think there must be some other solution. – Nirav Tukadiya Oct 21 '13 at 11:00
1

For your problem as seen in your screenshot your background have repeatable texture. Crop the image for texture and use repeatable background in place of single image. You can use following XML for repeatable background bg_repeat.xml

 <?xml version="1.0" encoding="utf-8"?>
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
 android:src="@drawable/background" 
 android:tileMode="repeat" /> 

background

background.png

give your cropped image as src here and put this XML file in your drawable. Now, in your layout do this -

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity" >

        <ImageView 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_repeat"/>

    </LinearLayout>

IMO this will serve your purpose and it will also save you some bites.

Nitin Joshi
  • 128
  • 1
  • 10
  • actually i didn't used different icons in footer.they yet to be implemented.they are different menus.so i can't use same imageview for all images. – Nirav Tukadiya Oct 30 '13 at 13:28
  • So, basically u r trying to make custom action bar with buttons/image views on it. If so imo you can use table layout and center align each image view inside each column. – Nitin Joshi Oct 31 '13 at 06:33
  • that is also a good idea but i had implemented it using weights. – Nirav Tukadiya Oct 31 '13 at 07:48
1

The dp pixels are density independent, not proportion independent. The difference in proportion of height to width between the two devices is the issue you are having, not an occurrence of non-standard dp. The only proper solution is to adjust the weight based on difference in proportion.

If density independent pixels were dependent on the pixels per inch, a density dependent unit, then they would also be density dependent.

D. Bunnell
  • 463
  • 6
  • 12
  • thank for the answers.actually i found the same thing after googling this thing and i was not sure that i have no option except using weights.i thought that there might be some other solution and i need strong reason why it is not possible.thanks. – Nirav Tukadiya Oct 30 '13 at 13:32
1

I think you need to work with weight here.Just put the same code in your XML and see the difference:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1" 
    android:gravity="center">

    <ImageView
        android:id="@+id/ft_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />
</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1" 
    android:gravity="center">

    <ImageView
        android:id="@+id/ft_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />
</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:gravity="center" >

    <ImageView
        android:id="@+id/ft_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />
</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:gravity="center" >

    <ImageView
        android:id="@+id/ft_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />
</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1" 
    android:gravity="center">

    <ImageView
        android:id="@+id/ft_5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:src="@drawable/ico_test" />
</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1" 
    android:gravity="center">

    <ImageView
        android:id="@+id/ft_6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:src="@drawable/ico_test" />
</LinearLayout>

Akhilesh Sk
  • 451
  • 4
  • 18
0

You just cannot support all the devices, Either you can create different layouts or different drawables to target each device.

Instead of linear layout use Relative layout that will be better for all devices.

  • "Instead of linear layout use Relative layout that will be better for all devices" makes no sense at all. In this scenario it's best to use a LinearLayout in combination with layout_weights. – Jeffrey Klardie Oct 30 '13 at 13:27