固定尺寸图像的可绘制和 Android 屏幕像素密度

Drawable and Android screen pixel density for fixed-size image

我正在处理与此问题相关的应用程序中的问题。看看你能不能帮我:

在我的例子中,我有一个显示标尺的 ImageView,然后我需要以实际大小显示这条规则,它不需要随着屏幕尺寸或密度的增加或缩小。以我的 Moto G3 为基础,它工作得很好,但是当测试其他设备时,它会失去标尺的实际尺寸,因为图像试图适应屏幕尺寸。

尺子图片为 PNG 格式,尺寸为 3600 像素 x 155 像素,最大尺寸为 30 厘米,在 LinearLayout 水平线内。在我的 Moto G3 可见区域是 10 厘米,例如更大的屏幕它应该显示更大的标尺区域(例如 11 到 15 厘米),但它在屏幕的视野中只有 10 厘米,显示它随着设备的显示设置和密度而增长和缩小。

之前每个资源(xxhdpi、xhdpi等)都有一张RAGUA的图片,所以我决定把它迁移到Android的assets文件夹,但还是有同样的问题。

您知道如何修复它吗?

代码如下:

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

正如我所说,在我为资产创建图像后,我开始将其设置为 java:

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

您应该在多屏幕

中为 运行 阅读此 guide

由于 Understanding Density Independence In Android,您可以按如下方式计算这些值

以下是您可以为您的设备 (Moto G3) 计算的方法

  1. 30 厘米 = 11.811 英寸
  2. Moto G3 屏幕密度桶是 xhdpi - 320dpi
  3. 320px ~= 1 英寸
  4. 320px * 11.811in ~= 3780px

通过这些步骤,您可以计算出您的图片应该有多大。

现在,不要为不同的屏幕密度提供不同的标尺图像,而是将高质量图像放在 drawable-anydpi 文件夹中,因为 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. 由于 '-nodpi, -anydpi, and WTF?' article from The CommonsBlog

不幸的是,您不能在布局 xml 文件中直接使用计算值 - ImageView 大小需要在 Java 代码中动态更改。

上面的解决方案应该给你 decent 准确度(可能相差 10%),但你可以将 DensityMetrics 与默认显示一起使用以获得实际的水平和垂直密度,这将帮助您更精确地计算图像像素大小。

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;

编辑

480dp 的计算:

  1. 30 厘米 = 11.811 英寸
  2. 密度桶 xxhdpi - 480dp
  3. 480px ~= 1in
  4. 480px * 11.811in ~= 5669px

我不确定您的答案是否正确,因为之前的答案似乎并不令人满意。我曾经遇到过同样的问题 - 我需要这个 ImageView 在大量设备上具有相同的大小而不缩放。我通过在 dp 中为 layout_widthlayout_height

提供定义值解决了我的问题