如何针对不同DPI区分dimens文件夹?解决Pixel与Moto X4布局适配问题
首先得搞清楚为什么会出现这个情况:Android的values-xxhdpi对应的是320dpi到480dpi之间的设备,所以你的Pixel(420dpi)和Moto X4(480dpi)都会匹配这个文件夹。但480dpi刚好是xxxhdpi的起始阈值(xxxhdpi对应480dpi及以上),系统在渲染时会把xxhdpi的资源按比例放大,导致Moto X4上的布局看起来过大。
给你几个可行的解决方案,按需选择:
使用精确密度限定符
直接针对特定DPI创建资源文件夹,比如values-420dpi和values-480dpi,把对应设备的 dimens 值分别放进去。Android系统会优先匹配精确的DPI文件夹,如果找不到才会 fallback 到通用的xxhdpi文件夹。这种方法最直接,适合你已经明确知道设备DPI的场景。利用xxxhdpi资源桶
既然Moto X4是480dpi(刚好触发xxxhdpi的阈值),你可以把适配Moto X4的 dimens 放到values-xxxhdpi文件夹里。这样480dpi的设备会优先加载xxxhdpi的资源,而420dpi的Pixel还是会用xxhdpi的资源,自然就能区分开两者的布局大小。使用最小宽度(sw)限定符
如果你的设备不仅DPI不同,屏幕宽度的dp值也有差异,可以用最小宽度限定符来区分。先计算两个设备的最小宽度dp:- Pixel(420dpi,1080px宽):
1080 / (420/160) ≈ 411dp,创建values-sw411dp - Moto X4(480dpi,1080px宽):
1080 / (480/160) = 360dp,创建values-sw360dp
把对应设备的 dimens 放到各自的sw文件夹里,这种方式更适配不同屏幕尺寸的设备,灵活性更高。
- Pixel(420dpi,1080px宽):
另外要注意资源加载的优先级:精确DPI限定符 > 密度范围限定符 > 通用密度桶(xxhdpi/xxxhdpi);而最小宽度限定符的优先级高于密度限定符,所以如果同时存在,系统会优先选择sw对应的文件夹。
内容的提问来源于stack exchange,提问作者Rohit Deshmukh

