如何处理安卓屏幕碎片?
我希望只编写一次布局和代码,以便它在所有设备上看起来都很好。 我已经尝试了很多方法(是的,包括谷歌建议的,使用DP并添加多个布局文件),但没有一个真正解决每次有一个具有随机分辨率的新设备时必须处理新情况的问题和密度。 DP 的使用只是一个 XML 技巧,它让尺寸在所有屏幕上保持相同,就像一把尺子一样(例如,1 厘米在所有屏幕上保持 1 厘米),所以它实际上不是一个解决方案。
我还使用了权重和代码技巧来设置正确的尺寸和位置,但对于这样一个简单的任务来说,工作量太大了。
我听说谷歌正在研究这个问题的解决方案以及新冰淇淋三明治版本的版本碎片,但我没有听到/读到任何关于这个问题的新消息。 不仅如此,android需要支持的多种密度和分辨率的图表也越来越大: http://developer.android.com/guide/practices/screens_support.html
遗憾的是,许多其他技术已经解决了这个问题:苹果有它(自动将应用程序从 iphone 3g 扩展到 iphone 4),adobe 有它(flash),甚至微软也有它(使用viewbox,在 silverlight、wpf 和 WP 上)。甚至电视也必须处理这个问题,而且它们做得很好。
我并不是在寻求魔法,只是在寻求一种扩展一切的方法。如果视图的大小为屏幕的 W%、H%,并且位于屏幕的 X%、Y% 的位置,则它应该在所有屏幕上保持这种方式,并且如果重要的话还允许我们保持宽高比对我们来说足够了。 为什么我们需要考虑分辨率和密度?我们和图形团队都感到困惑。
所以总而言之,我认为并希望很多人像我一样思考,也许有人制作了一个很好的 SDK 来解决这一切?
@chubbard:DP 效果不佳,因为它会让所有屏幕的内容保持完全相同,就像标尺一样。如果某些内容位于屏幕的 3/4 中,那么在另一个屏幕上就不会如此(它甚至可能在屏幕之外或发生其他奇怪的事情,具体取决于您选择的布局)。 DP 是一个固定值,仅根据密度转换为每个设备上的像素。因此,对于 wvga800 (hdpi-480x800) 和 wvga854(hdpi-480x854) 之间的差异,DP不会改变任何东西,并且你得到54个像素,你不知道如何处理它们。如果您想为 wvga854 添加一些内容,则不会为 wvga800 显示该内容。更糟糕的是,在谈论 Android 布局时,这两个屏幕之间没有区别 - 它们都属于普通 hdpi 的同一类别。
另外,如果您使用 DP,在一个屏幕上图像/按钮看起来不错,但在其他屏幕上,与屏幕的其余部分相比,它们看起来很小,所以这确实不是一个好的解决方案。 我也不明白为什么我们有多个可绘制文件夹通常设置为取决于密度。它只会为图形团队带来更多工作,并使应用程序的尺寸比实际尺寸大得多,因此,市场可能不接受它(因为尺寸太大),甚至更糟 - 设备不会接受它能够下载应用程序(例如,Galaxy S 上的旧操作系统版本无法下载和安装大小超过 30MB 的应用程序)。
@adamp:我没有说任何关于absoluteLayout的事情。它具有我希望像其他布局一样克服的不良行为。唯一允许缩放的布局是 LinearLayout (使用权重),但需要大量标签和文字来完成一项简单的任务。 关于我想要什么,我已经写了:我希望一切都能规模化。互联网上有大量的例子,你可以看到它工作得很好,即使在闪存上也是如此。只需打开一个完整的窗口 flash/silverlight 内容并调整窗口大小。如果程序员设置正确,其中的所有内容都会根据与原始大小相比的新大小进行缩放。 顺便说一句,谢谢您的 gridlayout 注释。我不知道。然而,它似乎也无法扩展任何东西。
@andreasg:现在这很有趣。你是如何处理图像的?你能尝试下一个“谜语”吗? 假设您有一张人脸(或 Android :) 的图像,该图像应适合屏幕(并保持其纵横比),并且您有另一张以不同颜色着色的眼睛图像,您将如何将它们放在上面另一个顶部(可能使用框架布局),以便它在所有设备上看起来都相同(缩放),无论您处于横向还是纵向模式?
i wish to write the layout and code just once so that it would look good on all devices .
i've tried many ways (yes, including what google suggests, to use DP and also add multiple layout files) , but none really solves the problem of having to deal with a new situation each time there is a new device with a random resolution and density.
the DP usage is just an XML trick that lets the dimensions stay the same on all screens like a ruler (for example , 1cm stays 1cm on all screens) ,so it's really not a solution.
i've also used weights and and code tricks to set the correct sizes and positions, but it's just too much work for such a simple task.
i've heard that google was working on a solution for this matter as well as versions fragmentations for the new ice cream sandwich version , but i didn't hear/read anything new about this matter.
not only that, but the chart of multiple densities&resolutions that android needs to support is getting bigger and bigger :
http://developer.android.com/guide/practices/screens_support.html
it's a shame that so many other technologies already had a solution for this problem : apple has it (automatically scaled the apps from iphone 3g to iphone 4) , adobe has it (flash) and even microsoft has it (using viewbox , on silverlight, wpf and WP) . even TVs have to handle this problem , and they do it just fine.
i'm not asking for magic, just for a way to scale everything . if a view was the size of W%,H% of the screen , and was on position of X%,Y% of the screen , it should stay this way on all screens , and also allow us to keep aspect ratio if it's important enough for us.
why do we need to bother with resolutions and densities? it's just confusing , both us and the graphics teams .
so in conclusion, i think and hope that many think like me, and maybe someone made a nice sdk that solves it all ?
@chubbard : DP doesn't work well since it will let things stay exactly the same for all screens just as a ruler . if something was in the 3/4 of the screen it won't be so on another screen (it might even be outside of the screen or have other weird things going on , depending on which layout you've chosen). DP is a fixed value which only being translated to pixels on each device based on the density alone. so , for the difference between wvga800 (hdpi-480x800) and wvga854(hdpi-480x854) , the DP won't change anything, and you get 54 pixels that you don't know what to do with them. if you want to put there something for the wvga854 , it won't be shown for the wvga800 . even worse , there is no difference between those 2 screens when talking about android layouts - they both sit under the same category of normal-hdpi.
also, if you use DP , on one screen the image/button looks ok , but on other screens they look so tiny compared to the rest of the screen , so it really can't be a good solution.
i also don't get why we have multiple drawable folders usually set to be depending on density . it only makes more work for the graphics teams and make the app to be in a much larger size than it is , and because of this , the market might not accept it (because of too large size) or even worse - devices won't be able to download the app (old OS versions on galaxy S , for example , cannot download&install apps that are more than 30MB size).
@adamp : i didn't say anything about absoluteLayout . it has the exact bad behavior that i wish to overcome as the rest of the layouts . the only layout that somehow allows scaling is linearLayout (using weights) , but it takes a lot of tags and writings to do a simple task .
about what i want, i already wrote it: i want that everything would scale . there are tons of examples on the internet where you can see that it works fine , even on flash . just open a full window flash/silverlight content and resize the window . if the programmer has set things right, everything in it will scale according to the new size compared to the original size.
btw, thank you for the note of gridlayout . i didn't know of it . however, it seems that it, too can't scale anything .
@andreasg : now this is interesting . how did you handle images? can you please try out the next "riddle" ?
suppose you have an image of a human face (or of android :) ) that should fit the screen (and keep its aspect ratio) , and you have another image of its eyes colored in a different color , how would you put them one on top of the other (probably using framelayout) so that it would look the same (scaled) on all of the devices , no matter if you are on landscape or portrait modes ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您应该仅在您希望应用程序的行为方式发生较大变化时使用完全不同的布局,而不是在单个设备类(例如手机)中屏幕尺寸发生微小变化时使用。您可以提供针对横向模式进行优化的布局的
-land
变体,也可以提供-sw600dp
变体来为 7 英寸左右的平板电脑呈现不同的信息架构" 或更大。您不应该使用它来为 WVGA 与 qHD 手机显示屏提供不同的布局。这样做只会为您自己带来大量额外的工作。dp是一个用于处理不同密度的工具,它不会有帮助对于差异处理屏幕尺寸和宽高比差异的解决方案是使用框架中提供的布局管理器来适应当前设备,您可以通过扩展
ViewGroup
并覆盖onMeasure
和onLayout
方法。 API 14 添加了GridLayout
,它提供了更多功能选项也是如此。针对这些差异进行设计确实需要采用不同的方法来解决问题。除非您想自己做很多工作,否则您无法通过绝对屏幕坐标来思考来解决问题。考虑一下布局中的组件如何相对彼此组合在一起,以及哪些部分应该扩展以占用比可用的最小配置更多的空间。
从百分比角度思考是一个好的开始,这正是使用
LinearLayout
的权重特性。但是,如果您想指定某个视图应保持特定的宽高比,您将需要考虑如何对其进行限制、用什么来填充多余的空间,以及这些决定是否会为您的应用程序带来良好的用户体验。 (例如,没有用户希望使用本身带有信箱的应用程序,并且仅在中间的固定宽高比框中显示真实内容。)对此没有神奇的解决方案,因为只有您知道这些东西在您的应用程序中应如何表现。 Android 会帮助你,但你必须告诉它你想要什么。
也许您可以发布有关您遇到问题的特定设计的问题,stackoverflow 上的某人可以提供一些建议。
You should only be using completely different layouts for large changes in how you want your app to behave, not for minor variances in screen size within a single device class such as phones. You might provide a
-land
variant of your layouts that are optimized for landscape mode, or you might provide a-sw600dp
variant to present a different information architecture for tablets of around 7" or larger. You should not use this to provide different layouts for a WVGA vs. a qHD phone display. Doing so will only create a lot of extra work for yourself.dp is a tool for working with different densities, it will not help for variances in size and aspect ratio. The solution for working with variance in screen size and aspect ratio is to use the layout managers provided in the framework to adapt to the current device. You can quite easily write your own by extending
ViewGroup
and overriding theonMeasure
andonLayout
methods if you come to a situation where you truly need custom behavior. API 14 addedGridLayout
, which offers further options as well.Designing for these variances does require a different approach to the problem. You cannot approach the problem by thinking in absolute screen coordinates unless you want to make a lot of work for yourself. Think about how the components in your layout fit together relative to one another, and which pieces should expand to consume more space than your minimum configuration when it is available.
Thinking in terms of percentages is a good start and that's exactly the kind of results you'll get by using
LinearLayout
's weight feature. But if you want to specify that a certain view should maintain a specific aspect ratio you will need to think about how that should be bounded, what will fill any excess space, and whether or not those decisions will produce a good user experience for your app. (For example, no user wants to use an app that letterboxes itself and only shows real content in a fixed aspect ratio box in the middle.)There is no magic solution to this since only you know how these things should behave in your app. Android will help you but you have to tell it what you want.
Perhaps you could post a question about a specific design that you are having trouble with and someone here on stackoverflow could offer some suggestions.
我为每个屏幕尺寸绘制具有正确比例的自定义视图的方法是获取实际的屏幕密度:
例如,为具有 16 个密度独立像素的自定义视图设置字体大小,
这就是全部魔力。我希望这能解决您的问题。
my way to draw custom views with the right scale for each screen size is to get the actual screen density:
and for example setting a font size for a custom view with 16 density independent pixels
Thats the whole magic. I hope this will solve your problem.