为什么要屏幕适配?品牌机型碎片化、屏幕尺寸碎片化、操作系统碎片化如果元素在不同尺寸和分辨率的Android手机上显示效果相同,我们就需要适配屏幕。基本概念屏幕尺寸屏幕尺寸是指屏幕对角线的长度,单位是英寸,1英寸=2.54厘米屏幕分辨率手机水平和垂直像素的总和,单位是像素(pixel),1px=1pixel,例如1080x1920,即宽度方向有1080个像素点,高度方向有1920个像素点。屏幕像素密度是每英寸的像素数,单位是dpi,dotsperinch。为简单起见,Android将所有屏幕密度分为六种通用密度:低、中、高、超高、超超高和超超超高。ldpi(低)~120dpimdpi(中)~160dpihdpi(高)~240dpixhdpi(超高)~320dpixxhdpi(超高)~480dpixxxhdpi(超超高)~640dpidpi_exampleScreendensityindependentpixelsdp(dip)DensityIndependentPixels,即与密度无关的像素。160dpi,1dp=1px240dpi,1dp=1.5px320dpi,1dp=2px480dpi,1dp=3px640dpi,1dp=4px在低、中、高屏幕密度下使用px的效果-test-bad在低、中、高屏密效果dimen_example2独立尺度像素spScaleIndependentPixels,即sp或sip。Android开发时,使用该单元设置文字大小,可根据fontsize***项进行缩放。建议使用12sp、14sp、18sp和22sp作为字体大小。不建议使用奇数和小数,容易造成精度损失。小于12sp的字体对于用户阅读来说太小了。屏幕适配的图像适配在设计图标时,5种主流像素密度(mdpi、hdpi、xhdpi、xxhdpi和xxxdpi)应该按照2:3:4:6:8的比例进行缩放。比如一张启动图片ic_launcher.png,它在每个pixeldensity文件夹下的大小为:)144*144xxxhdpi(ultra-ultra-ultra-high)192*192存在的问题每组分辨率产生一组图片,其中添加很多艺术或设计工作。Android工程文件的apk包变得很大。解决方案AndroidSDK加载图片过程AndroidSDK会根据屏幕密度自动选择相应的资源文件进行渲染加载。例如SDK检测到您手机的分辨率为xhdpi,会优先在xhdpi文件夹中寻找对应的图片资源;如果没有图片资源,会在分辨率高的文件夹中查找,比如xxhdpi,直到找到同名的图片资源,缩小为xhpi图片;搜索速率较高的文件夹,如hdpi,直到找到同名图片资源,将其放大为xhpi图片。根据加载图片的过程可以得出,理论上提供一组图片就可以了。那么应该提供哪种分辨率规格呢?原则上越高越好,同时结合当前主流分辨率屏幕自动拉伸图片weight的使用weight_examples当layout_width为0dp,layout_weight分别为1和2<按钮android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="2"android:text="weight=2"/>当layout_width为match_parent,layout_weight分别为1和2权重计算宽度=原始宽度+权重比例*layout_width为0dp时的剩余宽度,layout_weight分别为1和2***button:width=0+1/3*screenwidth=1/3screenwidth第二个button:width=0+2/3*screenwidth=2/3screenWidth当layout_width为match_parent时,layout_weight为1和2***按钮:width=屏幕宽度+1/3(屏幕宽度-2屏幕宽度)=2/3屏幕宽度第二个按钮:width=屏幕宽度+2/3(ScreenWidth-2ScreenWidth)=1/3ScreenWidth布局使用相对布局,禁用绝对布局限定符大小限定符在手机上的较小屏幕上,加载布局文件夹在平板电脑和电视上的布局在屏幕(>7英寸)上,加载Android3.2之前的布局大文件夹布局宽度限定符在手机的较小屏幕上,加载标准7英寸平板电脑的布局文件夹布局(最小宽度为600dp),加载Android3.2及以后版本layout-sw600dp文件夹的布局。布局别名适配手机单面板(默认)布局:res/layout/activity_main.xml适配>7寸平板(Android3.2之前)双面板布局:res/layout-large/activity_main.xml适用于尺寸>7寸平板双屏布局(Android3.2后):res/layout-sw600dp/activity_main.xml***两个文件的xml内容完全一致,这会带来:文件名的重复会带来一系列的维护问题,修改一个文件,可能会忘记修改另一个。所以为了解决这个重复问题,我们引入了布局别名。手机的单面板(默认)布局:res/layout/activity_main.xml平板电脑>7英寸的双面板布局:res/layout/activity_twopanes.xmlresalues/layout.xml@layout/activity_mainresalues-large/layout.xml@layout/activity_twopanesresalues-sw600dp/layout.xml@layout/activity_twopanessetContentView(R.layout.main);屏幕方向限定符res/layout-landres/layout-portres/layout-sw600dp-landres/layout-sw600dp-port屏幕适配dimen适配Nexus4(4.7inches768x1280:xhdpi)NexusS(4inches480x800:hdpi)d即使imen_example2使用了dp,依然无法解决屏幕分辨率适配问题。我们可以针对不同的屏幕创建不同的dimen值resalues/dimens.xml180dp160dpresalues-480x800/dimens.xml113dp100dp屏幕适配之百分比布局官方文档GithubSample自适应用户界面,用于屏幕适配newsreader_landnewsreader_port时NewsReader是横屏的,是双面板,左边是HeadLinesFragment,右边是ArticleFragment。点击新闻标题可以切换ArticleFragment的内容。NewsReader在竖屏时,是一个只有一个HeadLinesFragment的单面板。点击新闻标题跳转到ArticleActivity显示新闻内容。所以,要实现这样的横竖屏适配,仅仅通过布局是无法完成的。不同业务逻辑的处理也需要通过编写代码来完成。这是我们的自适应用户界面。使用布局别名resalues/layouts.xml@layout/onepane_with_barfalseresalues-sw600dp-land/layouts.xml@layout/twopanestrueresalues-sw600dp-端口/layouts.xml@layout/onepanefalse判断是否为单面板或者双面板ViewarticleView=findViewById(R.id.article);mIsDualPane=articleView!=null&&articleView.getVisibility()==View.VISIBLE;//如果能找到ArticleFragment,就是双面板的不同业务逻辑,单面板和双面板publicvoidonHeadlineSelected(intindex){mArtIndex=index;if(mIsDualPane){//displayitonthearticlefragmentmArticleFragment.displayArticle(mCurrentCat.getArticle(index));}else{//useseparateactivityIntenti=newIntent(this,ArticleActivity.class);i.putExtra("catIndex",mCatIndex);i.putExtra("artIndex",index);开始活动(我);}}