一、什么是屏幕适配
随着移动设备的不断更新迭代,屏幕的大小和分辨率也越来越多样化,为了保证在不同大小和分辨率的屏幕上能够正常显示,就需要进行屏幕适配。屏幕适配就是指在不同分辨率和尺寸的屏幕上,展示出大小和比例相同的UI效果。
Android提供了各种适配方案,包括使用不同尺寸的图片、使用dp等尺寸单位、使用不同的布局文件等。但这些方法的缺点是需要手动适配,并且不同屏幕的适配方式不同,为开发工作带来了很多不便。
二、屏幕适配方案ScreenMatch的特点
ScreenMatch是一种全局自动适配方案,将适配的工作放在运行时完成。它可以在不同分辨率和尺寸的屏幕上,保持UI显示的比例和大小相同,减少开发过程中的适配工作,并且实现了全局适配,无需手动适配。
ScreenMatch的实现原理是将UI像素值与目标屏幕尺寸的像素值进行比较,计算出一个缩放因子,再根据缩放因子来实现UI的适配。
三、ScreenMatch的实现原理
ScreenMatch的实现原理可以分为如下几个步骤:
1. 获取当前屏幕信息
private static DisplayMetrics sMetrics = new DisplayMetrics(); WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); display.getMetrics(sMetrics);
通过WindowManager获取Display对象,再通过Display对象获取DisplayMetrics对象,获取当前屏幕的信息,包括屏幕宽度、高度、密度等。
2. 计算缩放因子
public static float getScreenMatchScale(Context context, float targetDensity) { DisplayMetrics sMetrics = getResources().getDisplayMetrics(); int widthPixels = sMetrics.widthPixels; int heightPixels = sMetrics.heightPixels; float density = sMetrics.density; float screenWidth = widthPixels / density; float screenHeight = heightPixels / density; float targetWidth = screenWidth; if (screenWidth > screenHeight) { targetWidth = screenHeight; } return targetDensity / (targetWidth / 360f); }
根据获取到的屏幕信息和指定的目标屏幕密度,计算出缩放因子。在这里,我们将屏幕宽度/屏幕密度作为目标屏幕的宽度,如果屏幕宽度比屏幕高度大,就将屏幕高度/屏幕密度作为目标屏幕的宽度,最后根据目标屏幕的宽度和360这个参考值,计算出缩放因子。
3. 修改应用的显示密度
public static void setCustomDensity(Activity activity, final Application application) { final DisplayMetrics sMetrics = application.getResources().getDisplayMetrics(); float targetDensity = sMetrics.widthPixels / 360f; float targetScaledDensity = targetDensity * (sMetrics.scaledDensity / sMetrics.density); int targetDensityDpi = (int) (160 * targetDensity); sMetrics.density = targetDensity; sMetrics.scaledDensity = targetScaledDensity; sMetrics.densityDpi = targetDensityDpi; final DisplayMetrics sMetricsActivity = activity.getResources().getDisplayMetrics(); sMetricsActivity.density = targetDensity; sMetricsActivity.scaledDensity = targetScaledDensity; sMetricsActivity.densityDpi = targetDensityDpi; }
将应用的显示密度进行修改,使用我们计算出的缩放因子来修改屏幕密度和字体比例,实现全局适配。在这里,我们将sMetrics.widthPixels/360f作为目标密度,调整应用的显示密度来适配屏幕。
四、ScreenMatch的使用方法
使用ScreenMatch进行全局适配的方法也很简单,只需要在Application的onCreate方法中调用setCustomDensity进行初始化即可。
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); ScreenMatch.setCustomDensity(this, this); } }
当然,如果应用中存在特殊需要,并不想使用ScreenMatch进行适配,可以在对应的布局文件中添加tools:ignore="ScreenMatch"属性即可。
至此,我们已经全面解析了屏幕适配方案ScreenMatch的实现原理。使用ScreenMatch,我们可以省去很多冗余的适配工作,提高开发效率,更加专注于UI实现。