为具有不同ppi像素的多个设备设置图像

时间:2013-10-21 09:18:31

标签: android android-layout android-xml android-drawable

我正在根据官方谷歌文档设置不同设备的图像。根据谷歌文档,我们应该始终使用dp(密度无关像素),因为不同设备的像素可能会有所不同。 所以我按照dp(密度独立像素)管理图像。 我把图像放在可绘制的xhdpi,hdpi,mdpi和ldpi中。它适用于大多数设备,但对于不同的设备,ppi像素可能因设备而异,因此dp(密度无关像素)不固定,因此我根据dp(密度无关像素)的所有计算都出错并且无法正确设置。 / p>

让我用例子解释一下。 这是我正在设置的xml:

<?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>

当我在Micromax canvas 4(294 ppi像素)中看到这个布局时,它看起来很完美。 但在Google Nexus 4(318 ppi像素)中,它会从右侧留下更多空间(您可以在我附加的图像中看到它。)。

我试图获得以下细节

density :
dpHeight :
dpWidth :

使用以下java代码:

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;

我得到了关于nexus 4和canvas 4的以下结果:

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

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

正如您在这里看到的那样dp(密度无关像素)因这些设备而异 我认为这是因为不同的ppi像素所以我所有的计算根据dp(密度无关像素)出错了。 如果dp没有修复,我怎么能管理图像。??

我还附加了图片的屏幕截图,如布局4和nexus 4中的布局。

我也提到了这个问题How do I convert ppi into dpi for Android images?

我知道我可以使用布局权重调整布局,但我认为必须有另一种解决方案来解决这个问题。

请参阅并帮助我解决问题。

Nexus 4 Screenshot Canvas 4 screenshot

7 个答案:

答案 0 :(得分:4)

您无法支持所有设备,您可以创建不同的布局或不同的绘图来定位每个设备。

您可以做的最好的事情就是制作一个灵活的用户界面,按比例划分视图,并实现 WEIGHT 。只需使用权重将UI分成这样的比例

<?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>

答案 1 :(得分:1)

试试这个

<?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>

答案 2 :(得分:1)

我这样做

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));
....

以相同的方式为每个按钮设置..

Tabbar概念在另一方面起作用..

答案 3 :(得分:1)

对于您在截图中看到的问题,您的背景具有可重复的纹理。裁剪图像纹理并使用可重复背景代替单个图像。您可以将以下XML用于可重复的背景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

将裁剪后的图像设为src,并将此XML文件放入drawable中。现在,在您的布局中执行此操作 -

    <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这将满足您的目的,它也可以为您节省一些费用。

答案 4 :(得分:1)

dp像素与密度无关,与比例无关。两个设备之间高度与宽度的比例差异是您遇到的问题,而不是非标准dp的出现。唯一合适的解决方案是根据比例差异调整重量。

如果与密度无关的像素依赖于每英寸像素(密度相关单位),那么它们也将取决于密度。

答案 5 :(得分:1)

我认为你需要在这里使用权重。只需在XML中添加相同的代码并查看差异:

<?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>

答案 6 :(得分:0)

您无法支持所有设备,您可以创建不同的布局或不同的绘图来定位每个设备。

而不是线性布局使用相对布局,这将更好地适用于所有设备。