[英]Best quality image allocation from resources based on resolution/density
我正在努力解决Android“多屏尺寸”领域的一项非常简单的任务。
我想要实现的目标
与屏幕宽度匹配的布局,具有9个补丁背景,其大小调整(仅水平,因为总是有足够的垂直空间)。 这是一个虚拟图像:
我的目标是,根据屏幕分辨率,使用一组不同的尺寸,例如,以尽可能高的分辨率显示图像。 320x45,480x67,600x87,720x101,无需任何缩小。 我希望有一个非程序化的解决方案。
具有上述图像尺寸的示例将是:
问题
整个Android资源分配围绕dp
s(与密度无关的像素),实际上我想根据实际可用像素显示图像。
如果我将480x67图像分配给res / drawable-mdpi,将600x87分配给res / drawable-hdpi,则图像将在5.4x800的480x显示器上正确显示 ,即mdpi显示。但是,4“480x800显示器符合hdpi和系统将指定600x87图像,这将不适合屏幕 。
我尝试了在线指南中描述的smallestWidth
参数,但这会产生奇怪的结果。 例如,一个3.7“480 x 800显示器(hdpi)使用我的drawable-sw320dp图像,尽管有一个drawable-sw480dp资源也可用。
提前致谢!
我相信通过组合密度和屏幕大小资源限定符,您可以实现接近最佳行为。
让我们假设这种资源文件夹结构:
drawable-normal-hdpi
- normal
大小规定最小宽度为320dp。 hdpi
指示1.5X dp到像素乘数。 因此, normal hdpi
存储桶的最小px宽度为480px。 我们在这里放了480px宽的图像。 drawable-normal-xhdpi
- 再次大小指示320dp但这次使用2倍乘数。 所以我们使用640px宽的图像。 drawable-xlarge-mdpi
- 大小意味着至少720dp。 mdpi
乘数是1X,所以我们使用720px宽的图像。 现在让我们看看一些设备,看看它们是如何落入这些存储桶的:
normal hdpi
。 实际px宽度:480px。 图像非常适合。 normal xhdpi
。 我们可以适应720px的图像,因此我们使用的640px图像并不是最佳的 - 但它非常接近。 xlarge mdpi
。 我们可以适合800px,我们的图像是720px。 再次不理想但足够接近。 最糟糕的情况:使用的图像质量可提高5-10%。 最佳表壳:完美贴合。
这种方法的主要缺点是你需要提供大量的资源和文件夹来考虑大小和密度的所有排列(如果你需要将它与更多的限定符组合用于区域设置,方向等,则更糟糕)。 但是,就我的Android理解而言,我不认为你可以在没有编码的情况下取得比这更好的东西。
关于smallestWidth
的评论:你的奇怪行为的例子实际上是预期的行为。 hdpi乘数为1.5 - 因此480px宽的hdpi显示器正好是320dp宽。 这使得drawable-sw320dp成为正确的选择,如文档所述。 我不确定你是否可以将smallestWidth
限定符与dpi限定符组合使用。 如果可能的话,您可能会获得比仅仅大小修饰符更准确的结果。 但这意味着图像质量提高5%会产生更多的排列。 可能不值得。
实际上,你的方法不是它应该如何。 我将为您推荐两种方法,一种是简单但以编程方式进行,另一种是使用自定义视图。
方法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);
在android中你有选项hdpi,mdpi,xdpi等。
为此,您必须根据设备分辨率创建不同的图像,并在确认设备分辨率和密度类别后将图像放在那里。
为了更多的参考,为什么它会发生你可以看到这里
在这里我解释一些图表可能对您有所帮助。
低密度小屏幕QVGA 240x320(120dpi):
drawable-small-ldpi(240x320)
drawable-small-land-ldpi(320x240)
低密度普通屏幕WVGA400 240x400(x432)(120dpi):
drawable-ldpi(240 x 400)drawable-land-ldpi(400 x 240)
中密度普通屏幕HVGA 320x480(160dpi):
drawable-mdpi(320 x 480)drawable-land-mdpi(480 x 320)
中密度大屏幕HVGA 320x480(160dpi):
drawable-large-mdpi(320 x 480)drawable-large-land-mdpi(480 x 320)
Galaxy Tab(240 dpi):
drawable-large(600 x 1024)drawable-large-land(1024 x 600)
高密度普通屏幕WVGA800 480x800(x854)(240 dpi):
drawable-hdpi(480 x 800)drawable-land-hdpi(800 x 480)
Xoom(中密度大,但1280x800 res)(160 dpi):
drawable-xlarge(800 x 1280)drawable-xlarge-land(1280 x 800)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.