4

我正在为 Android“多屏幕尺寸”领域的一项非常琐碎的任务而苦苦挣扎。

我想要达到的目标

与屏幕宽度匹配的布局,具有可调整大小的九个补丁背景(仅水平方向,因为始终有足够的垂直空间)。这是一个虚拟图像:水平可拉伸的九个补丁图像,左右两端有两个区域

我的目标是,根据屏幕分辨率,通过使用一组不同的尺寸,例如以最高分辨率显示图像。320x45、480x67、600x87、720x101,没有任何缩小。我希望有一个非编程的解决方案。

具有上述图像大小的示例是:

  • 3.7" Nexus One (480 x 800) - 480x67 图像看起来最好。
  • 4.7 英寸 Galaxy Nexus (720 x 1280) - 720x101 图像。
  • 4.7 英寸 Nexus 4 (768 x 1280) - 再次是 720x101 图像,拉伸到完整的 768 像素宽度并变为 768x101。

问题

整个 Android 资源分配围绕dps(与密度无关的像素)进行,而实际上我想根据实际可用像素显示图像。

如果我将 480x67 图像分配给 res/drawable-mdpi 并将 600x87 分配给 res/drawable-hdpi,则图像将在480x800 的 5.4" 显示器上正确显示,即 mdpi 显示器。但是,4" 480x800 显示器符合 hdpi 和系统会指定不适合屏幕的 600x87 图像

我尝试了在线指南smallestWidth中描述的参数,但这会产生奇怪的结果。例如,一个 3.7" 480 x 800 显示器 (hdpi) 使用我的 drawable-sw320dp 图像,尽管也有一个 drawable-sw480dp 资源可用。

分配具有最佳质量的可拉伸、宽度匹配图像的最佳方法是什么?没有任何非程序化的解决方案吗?

提前致谢!

4

3 回答 3

3

我相信通过结合密度和屏幕尺寸资源限定符,您可以实现接近最佳的行为。

让我们假设这种资源文件夹结构:

  • drawable-normal-hdpi-normal尺寸规定最小宽度为 320dp。hdpi指示 1.5X dp 到像素乘数。所以normal hdpi桶的最小px宽度是480px。我们在这里放了一张 480 像素宽的图片。
  • drawable-normal-xhdpi- 尺寸再次规定 320dp,但这次使用 2X 乘数。所以我们使用 640px 宽的图像。
  • drawable-xlarge-mdpi- 大小意味着至少 720dp。mdpi乘数是 1X,所以我们使用 720px 宽的图像。

现在让我们看看一些设备,看看它们是如何落入这些桶的:

  • 连结一号 - normal hdpi. 实际像素宽度:480 像素。图像完美契合。
  • 银河系 - normal xhdpi. 我们可以适应 720 像素的图像,因此我们使用的 640 像素的图像不是最佳的 - 但它非常接近。
  • Nexus 4 就像 Gnex 一样。
  • 连结 10.1 (1280X800) - xlarge mdpi. 我们可以适应 800px,我们的图像是 720px。再次不理想但足够接近。

最坏的情况:使用的图像质量可能提高 5-10%。最佳案例:完美契合。

这种方法的主要缺点是您需要提供大量资源和文件夹来考虑所有大小和密度的排列(如果您需要将其与更多的语言环境、方向等限定符结合起来,那就更糟了)。但是,就我对 Android 的理解而言,我认为如果不编码,您无法实现比这更好的事情。


关于smallestWidth:您的怪异行为示例实际上是预期的行为。hdpi 乘数是 1.5 - 所以 480px 宽的 hdpi 显示器正好是 320dp 宽。如文档所述,这使得 drawable-sw320dp 成为正确的选择。我不确定您是否可以将smallestWidth限定符与 dpi 限定符结合使用。如果可能的话,您可能会得到比尺寸修饰符更准确的结果。但这意味着图像质量提高 5% 需要更多的排列组合。可能不值得。

于 2014-05-23T09:25:08.330 回答
1

实际上,您的方法不是应该的。我会为你推荐 2 种方法,一种很简单,但是以编程方式进行,另一种是使用自定义视图。

方法 1 - 以编程方式

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int screenWidth = displaymetrics.widthPixels; 
    // this will determine "scale ratio" so using which image height and width won't matter 
    int imageOriginalHeight = 101; // your original image height        
    int imageOriginalWidth = 720; // your original image width
    int imageScaleHeight = (screenWidth*imageOriginalHeight) / imageOriginalWidth;

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth, imageScaleHeight);
    imageView.setLayoutParams(params);
    imageView.setImageResource(R.drawable.file);

方法 2 - 自定义视图

您可以使用Maurycy Wojtowicz 编写的名为ScaleImageView的自定义视图。

类定义如下:

此视图将通过确定是否设置了高度或宽度(精确大小或 match_parent)来自动确定宽度或高度,并根据图像尺寸缩放其他尺寸此视图还包含一个 ImageChangeListener,一旦发生更改,它就会调用 changed(boolean isEmpty)已对 ImageView

以下是您将如何实施它。

创建一个名为 ScaleImageView.java 的类并复制上面链接的内容。

在您的 xml 文件中,创建一个ScaleImageView,就像一样ImageView(我在下面写的示例是用于填充屏幕宽度,并据此缩放高度,因此右侧/左侧不会有空格)

    <com.project.customview.ScaleImageView
        android:id="@+id/scaleImageView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:src="@drawable/file" />

如果你需要在你的Activity中以编程方式声明和设置,也和使用ImageView一样:

imageView = (ScaleImageView)findViewById(R.id.scaleImageView);
imageView.setImageResource(R.drawable.file);
于 2014-05-08T05:55:56.987 回答
-1

在 android 中,您可以选择 hdpi、mdpi、xdpi 等。

为此,您必须根据设备分辨率创建不同的图像,并在确认设备分辨率和密度类别后将图像放在那里。

有关为什么会发生的更多参考,您可以在此处查看

在这里我解释一些图表可能对你有帮助。

低密度小屏幕 QVGA 240x320 (120dpi):

drawable-small-ldpi (240x320)
drawable-small-land-ldpi (320x240)

低密度普通屏幕 WVGA400 240x400 (x432) (120dpi):

可绘制 ldpi (240 x 400 ) 可绘制土地 ldpi (400 x 240 )

中等密度普通屏幕 HVGA 320x480 (160dpi):

可绘制 mdpi (320 x 480) 可绘制土地 mdpi (480 x 320)

中密度大屏幕 HVGA 320x480 (160dpi):

drawable-large-mdpi (320 x 480) drawable-large-land-mdpi (480 x 320)

银河标签(240 dpi):

drawable-large (600 x 1024) drawable-large-land (1024 x 600)

高密度普通屏幕 WVGA800 480x800 (x854) (240 dpi):

可绘制-hdpi (480 x 800) 可绘制-土地-hdpi (800 x 480)

Xoom(中等密度,大但 1280x800 res)(160 dpi):

drawable-xlarge (800 x 1280) drawable-xlarge-land (1280 x 800)

于 2014-05-28T09:34:44.113 回答