前言一个月前看到今日头条新的屏幕适配方案。类中一行代码即可适配。现在AndroidUtilCode1.18.0版本有适配方案。其相关函数在ScreenUtils中。相关API如下:adaptScreen4VerticalSlide:适配垂直滑屏屏幕带水平滑动cancelAdaptScreen:取消适配屏幕效果startActivity(starter);}@OverridepublicvoidinData{(ScreenUtils.isPortrait()){ScreenUtils.adaptScreen4VerticalSlide(this,360);}else{ScreenUtils.adaptScreen4Horizo??ntalSlide(this,360));}}@OverridepublicintbindLayout(){returnR.layout.activity_screen_adapt;}@OverridepublicvoidinitView(BundlesavedInstanceState,ViewcontentView){tvUp=findViewById(R.id.tv_up);tvDown=findViewById(R.id.tv_down);if(!ScreenUtils.isPortrait()){updateLayout();}}@OverridepublicvoiddoBusiness(){}@OverridepublicvoidonWidgetClick(Viewview){}publicvoidtoggleFullScreen(Viewview){ScreenUtils.toggleFullScreen(this);updateLayout();}privatevoidupdateLayout(){intstatusBarHeight=BarUtils。getStatusBarHeight();intstatusBarHeightInDp=SizeUtils.px2dp(this,statusBarHeight);ViewGroup.LayoutParamsupLayoutParams=tvUp.getLayoutParams();ViewGroup.LayoutParamsdownLayoutParams=tvDown.getLayoutParams();if(ScreenUtils.isFullScreen(this)){intheight=360/2;Strings=height+"dp";upLayoutParams.height=SizeUtils.dp2px(this,height);tvUp.setLayoutParams(upLayoutParams);tvUp.setText(s);down??LayoutParams.height=SizeUtils.dp2px(this,height);tvDown.setLayoutParams(downLayoutParams);tvDown.setText(s);}else{intheight=360/2-statusBarHeightInDp/2;Strings=height+"dp";upLayoutParams.height=SizeUtils.dp2px(this,height);tvUp.setLayoutParams(upLayoutParams);tvUp.setText(s);down??LayoutParams.height=SizeUtils.dp2px(this,height);tvDown.setLayoutParams(downLayoutParams);tvDown.setText(s);}}}1080x1920420dpi(xxhdpi)下面效果如下:768x1280320dpi(xhdpi)下效果如下:480x800240dpi(hdpi)下效果如下:320x480160dpi(mdpi)下效果如下:如上是适配效果纵向屏幕以360dp为宽度和宽屏幕以360dp为高度。原理如果你看过上面头条的适配文章,那么你可能已经知道原理了。不明白的可以继续看我的解释:原理是修改Activity的Resources#getDisplayMetrics中的density、densityDpi、scaledDensity。三个变量让它在设计图下显示为dp大小,因为Activity视图中所有维度的转换都会围绕以上三个变量进行。比如我们使用水平固定垂直滑动,设计图水平宽度为360以dp为例,那么我们强行修改设备的密度为360,然后按比例修改densityDpi和scaledDensity的值,那么这个Activity在任意设备下都会被强行转化为水平宽度为360dp的大小,因为可以垂直滑动,只要垂直方向是自适应高度按比例缩放,在任何设备上效果都是一致的,实现了屏幕适配。如果想取消屏幕适配,只需要将Application的Resources#getDisplayMetrics中的三个变量density、densityDpi、scaledDensity的值赋值给Activity对应的值即可。代码布什几行,如下所示:/***Adaptthescreenforverticalslide.**@paramdesignWidthInDpThesizeofdesigndiagram'swidth,indp,*e.g.thedesigndiagramwidthis720px,inXHDPIdevice,*thedesignWidthInDp=720/2.*/publicstaticvoidadaptScreen4VerticalSlide(finalActivityactivity,finalintdesignWidthInDp){adaptScreen,designWidthIndp);}/***Adaptthescreenforhorizo??ntalslide.**@paramdesignHeightInDpThesizeofdesigndiagram'sheight,indp,*e.g.thedesigndiagramheightis1080px,inXXHDPIdevice,*thedesignHeightInDp=1080/3.*/publicstaticvoidadaptScreen4Horizo??ntalSlide(finalActivityactivity,finalintdesignHeightInDp){adaptHeightInD};/,*fadaptHeightSeightInD(活动)**取消适应屏幕。**@paramactivityTheactivity。*/publicstaticvoidcancelAdaptScreen(finalActivityactivity){finalDisplayMetricsappDm=Utils.getApp().getResources().getDisplayMetrics();finalDisplayMetricsactivityDm=activity.getResources().getDisplayMetrics();activityDm.density=appDm.density;activityDm.scaledDensity=appDm.scaledDensity;activityDm.densityDpi=appDm.densityDpi;}/***参考自:https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA*/privatestaticvoidadaptScreen(finalActivityactivity,finalfloatsizeInDp,finalbooleanisVerticalSlide){finalDisplayMetricsappDm=Utils.getApp().getResources().getDisplayDisplayMetrics()=finalDisplay.getDisplayMetrics();(isVerticalSlide){activityDm.density=activityDm.widthPixels/sizeInDp;}else{activityDm.density=activityDm.heightPixels/sizeInDp;}activityDm.scaledDensity=activityDm.density*(appDm.scaledDensity/appDm.);activityDm.densityDpi=(int)(160*activityDm.density);}坑点之前写的SizeUtils.px2dp工具类是在Application的上下文中使用的,所以在写Demo横屏的时候适配了状态栏发现了一个小问题,尺寸总是错的,***突然y意识到Activity的Resources#getDisplayMetrics和Application的Resources#getDisplayMetrics是两个不同的引用,所以我的工具类给SizeUtils.px2dp扩展了一个context参数来适应Activity的尺寸转换,也就是Demo中的代码SizeUtils.dp2px(this,height),找到Application和ActivityResources#getDisplayMetrics的区别也方便我取消适配优化今日头条的实现。其实代码不需要他想的那么复杂。很多事情通常最后都有优雅的解决方案,而我的工具类中的实现就是这样。建议对于老项目,不要大费周章去改适配代码。对于新项目,我建议使用我的工具类中的use,这样可以让你感觉更好。就在BaseActivity中调用setContentView(xx)之前的适配代码,然后Long-winded一次,传入的第二个参数是设计的尺寸转换为dp尺寸。比如你要适配屏幕水平固定垂直滑动,设计的宽度是720px-XHDPI,那么转换成dp就是720/2=dp,我就不告诉你这个怎么实现了2出现了。这是Android的基础。不懂的可以补基础。如果代码涉及到px和dp、px和sp的转换,必须使用我的工具类SizeUtils.dp2px、SizeUtils.px2dp、SizeUtils.sp2px、SizeUtils.px2sp传入context的重载,不要省略contextso至于使用Application上下文,如果你不确定它是什么dpi,那么你的设计稿资源放在Justusewhateverisunderthedpi。比如你的资源放在drawable-xxhdpi,那么你就可以使用设计稿尺寸/3。固定dp尺寸,是不是很容易实现我们的百分比呢?计算完直接写xxdp就可以了,这样在所有设备上也是一定的比例。我们在哪里需要任何百分比布局?是的,没那么简单,更多风骚操作等你解锁。
