当前位置: 首页 > news >正文

上海做网站的知名企业WordPress主题启用出现错误

上海做网站的知名企业,WordPress主题启用出现错误,简单美食网站模板,使用vs2015做网站教程来源#xff1a;http://blog.csdn.net/zhaokaiqiang1992 更多#xff1a;Android AutoLayout全新的适配方式#xff0c; 堪称适配终结者 Android的屏幕适配一直以来都在折磨着我们这些开发者#xff0c;本篇文章以Google的官方文档为基础#xff0c;全面而深入的讲解了And… 来源http://blog.csdn.net/zhaokaiqiang1992 更多Android AutoLayout全新的适配方式 堪称适配终结者   Android的屏幕适配一直以来都在折磨着我们这些开发者本篇文章以Google的官方文档为基础全面而深入的讲解了Android屏幕适配的原因、重要概念、解决方案及最佳实践我相信如果你能认真的学习本文对于Android的屏幕适配你将有所收获  Android屏幕适配出现的原因重要概念 屏幕尺寸屏幕分辨率屏幕像素密度dpdipdpisppxmdpihdpixdpixxdpi解决方案 支持各种屏幕尺寸 使用wrap_contentmatch_parentweight使用相对布局禁用绝对布局使用限定符 使用尺寸限定符使用最小宽度限定符使用布局别名使用屏幕方向限定符使用自动拉伸位图支持各种屏幕密度 使用非密度制约像素提供备用位图实施自适应用户界面流程 确定当前布局根据当前布局做出响应重复使用其他活动中的片段处理屏幕配置变化最佳实践 关于高清设计图尺寸ImageView的ScaleType属性动态设置更多参考资料   Android屏幕适配出现的原因 在我们学习如何进行屏幕适配之前我们需要先了解下为什么Android需要进行屏幕适配。 由于Android系统的开放性任何用户、开发者、OEM厂商、运营商都可以对Android进行定制修改成他们想要的样子。 但是这种“碎片化”到底到达什么程度呢 在2012年OpenSignalMaps以下简称OSM发布了第一份Android碎片化报告统计数据表明 2012年支持Android的设备共有3997种。2013年支持Android的设备共有11868种。2014年支持Android的设备共有18796种。下面这张图片所显示的内容足以充分说明当今Android系统碎片化问题的严重性因为该图片中的每一个矩形都代表着一种Android设备。 而随着支持Android系统的设备(手机、平板、电视、手表)的增多设备碎片化、品牌碎片化、系统碎片化、传感器碎片化和屏幕碎片化的程度也在不断地加深。而我们今天要探讨的则是对我们开发影响比较大的——屏幕的碎片化。 下面这张图是Android屏幕尺寸的示意图在这张图里面蓝色矩形的大小代表不同尺寸颜色深浅则代表所占百分比的大小。 而与之相对应的则是下面这张图。这张图显示了IOS设备所需要进行适配的屏幕尺寸和占比。 当然这张图片只是4,4s,5,5c,5s和平板的尺寸现在还应该加上新推出的iphone6和plus但是和Android的屏幕碎片化程度相比而言还是差的太远。 详细的统计数据请到这里查看 现在你应该很清楚为什么要对Android的屏幕进行适配了吧屏幕尺寸这么多为了让我们开发的程序能够比较美观的显示在不同尺寸、分辨率、像素密度(这些概念我会在下面详细讲解)的设备上那就要在开发的过程中进行处理至于如何去进行处理这就是我们今天的主题了。 但是在开始进入主题之前我们再来探讨一件事情那就是Android设备的屏幕尺寸从几寸的智能手机到10寸的平板电脑再到几十寸的数字电视我们应该适配哪些设备呢 其实这个问题不应该这么考虑因为对于具有相同像素密度的设备来说像素越高尺寸就越大所以我们可以换个思路将问题从单纯的尺寸大小转换到像素大小和像素密度的角度来。 下图是2014年初友盟统计的占比5%以上的6个主流分辨率可以看出占比最高的是480*800320*480的设备竟然也占据了很大比例但是和半年前的数据相比较中低分辨率(320*480、480*800)的比例在减少而中高分辨率的比例则在不断地增加。虽然每个分辨率所占的比例在变化但是总的趋势没变还是这六种只是分辨率在不断地提高。 所以说我们只要尽量适配这几种分辨率就可以在大部分的手机上正常运行了。 当然了这只是手机的适配对于平板设备(电视也可以看做是平板)我们还需要一些其他的处理。 好了到目前为止我们已经弄清楚了Android开发为什么要进行适配以及我们应该适配哪些对象接下来终于进入我们的正题了 首先我们先要学习几个重要的概念。 重要概念 什么是屏幕尺寸、屏幕分辨率、屏幕像素密度 什么是dp、dip、dpi、sp、px他们之间的关系是什么 什么是mdpi、hdpi、xdpi、xxdpi如何计算和区分 在下面的内容中我们将介绍这些概念。 屏幕尺寸 屏幕尺寸指屏幕的对角线的长度单位是英寸1英寸2.54厘米 比如常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等 屏幕分辨率 屏幕分辨率是指在横纵向上的像素点数单位是px1px1个像素点。一般以纵向像素*横向像素如1960*1080。 屏幕像素密度 屏幕像素密度是指每英寸上的像素点数单位是dpi即“dot per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关在单一变化条件下屏幕尺寸越小、分辨率越高像素密度越大反之越小。 dp、dip、dpi、sp、px px我们应该是比较熟悉的前面的分辨率就是用的像素为单位大多数情况下比如UI设计、Android原生API都会以px作为统一的计量单位像是获取屏幕宽高等。 dip和dp是一个意思都是Density Independent Pixels的缩写即密度无关像素上面我们说过dpi是屏幕像素密度假如一英寸里面有160个像素这个屏幕的像素密度就是160dpi那么在这种情况下dp和px如何换算呢在Android中规定以160dpi为基准1dip1px如果密度是320dpi则1dip2px以此类推。 假如同样都是画一条320px的线在480*800分辨率手机上显示为2/3屏幕宽度在320*480的手机上则占满了全屏如果使用dp为单位在这两种分辨率下160dp都显示为屏幕一半的长度。这也是为什么在Android开发中写布局的时候要尽量使用dp而不是px的原因。 而sp即scale-independent pixels与dp类似但是可以根据文字大小首选项进行放缩是设置字体大小的御用单位。 mdpi、hdpi、xdpi、xxdpi 其实之前还有个ldpi但是随着移动设备配置的不断升级这个像素密度的设备已经很罕见了所在现在适配时不需考虑。 mdpi、hdpi、xdpi、xxdpi用来修饰Android中的drawable文件夹及values文件夹用来区分不同像素密度下的图片和dimen值。 那么如何区分呢Google官方指定按照下列标准进行区分 名称像素密度范围mdpi120dpi~160dpihdpi160dpi~240dpixhdpi240dpi~320dpixxhdpi320dpi~480dpixxxhdpi480dpi~640dpi在进行开发的时候我们需要把合适大小的图片放在合适的文件夹里面。下面以图标设计为例进行介绍。 在设计图标时对于五种主流的像素密度MDPI、HDPI、XHDPI、XXHDPI 和 XXXHDPI应按照 2:3:4:6:8 的比例进行缩放。例如一个启动图标的尺寸为48x48 dp这表示在 MDPI 的屏幕上其实际尺寸应为 48x48 px在 HDPI 的屏幕上其实际大小是 MDPI 的 1.5 倍 (72x72 px)在 XDPI 的屏幕上其实际大小是 MDPI 的 2 倍 (96x96 px)依此类推。 虽然 Android 也支持低像素密度 (LDPI) 的屏幕但无需为此费神系统会自动将 HDPI 尺寸的图标缩小到 1/2 进行匹配。 下图为图标的各个屏幕密度的对应尺寸 屏幕密度图标尺寸mdpi48x48pxhdpi72x72pxxhdpi96x96pxxxhdpi144x144pxxxxhdpi192x192px解决方案 支持各种屏幕尺寸 使用wrap_content、match_parent、weight 要确保布局的灵活性并适应各种尺寸的屏幕应使用 “wrap_content” 和 “match_parent” 控制某些视图组件的宽度和高度。 使用 “wrap_content”系统就会将视图的宽度或高度设置成所需的最小尺寸以适应视图中的内容而 “match_parent”在低于 API 级别 8 的级别中称为 “fill_parent”则会展开组件以匹配其父视图的尺寸。 如果使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬编码的尺寸视图就会相应地仅使用自身所需的空间或展开以填满可用空间。此方法可让布局正确适应各种屏幕尺寸和屏幕方向。 下面是一段示例代码 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:orientationvertical android:layout_widthmatch_parent android:layout_heightmatch_parent LinearLayout android:layout_widthmatch_parent android:idid/linearLayout1 android:gravitycenter android:layout_height50dp ImageView android:idid/imageView1 android:layout_heightwrap_content android:layout_widthwrap_content android:srcdrawable/logo android:paddingRight30dp android:layout_gravityleft android:layout_weight0 / View android:layout_heightwrap_content android:idid/view1 android:layout_widthwrap_content android:layout_weight1 / Button android:idid/categorybutton android:backgrounddrawable/button_bg android:layout_heightmatch_parent android:layout_weight0 android:layout_width120dp stylestyle/CategoryButtonStyle/ /LinearLayout fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_widthmatch_parent / /LinearLayout     下图是在横纵屏切换的时候的显示效果我们可以看到这样可以很好的适配屏幕尺寸的变化。 weight是线性布局的一个独特的属性我们可以使用这个属性来按照比例对界面进行分配完成一些特殊的需求。 但是我们对于这个属性的计算应该如何理解呢 首先看下面的例子我们在布局中这样设置我们的界面 我们在布局里面设置为线性布局横向排列然后放置两个宽度为0dp的按钮分别设置weight为1和2在效果图中我们可以看到两个按钮按照12的宽度比例正常排列了这也是我们经常使用到的场景这是时候很好理解Button1的宽度就是1/(12) 1/3Button2的宽度则是2/(12) 2/3我们可以很清楚的明白这种情景下的占比如何计算。 但是假如我们的宽度不是0dp(wrap_content和0dp的效果相同)则是match_parent呢 下面是设置为match_parent的效果 我们可以看到在这种情况下占比和上面正好相反这是怎么回事呢说到这里我们就不得不提一下weight的计算方法了。 android:layout_weight的真实含义是:如果View设置了该属性并且有效那么该 View的宽度等于原有宽度(android:layout_width)加上剩余空间的占比。 从这个角度我们来解释一下上面的现象。在上面的代码中我们设置每个Button的宽度都是match_parent假设屏幕宽度为L那么每个Button的宽度也应该都为L剩余宽度就等于L-LL -L。 Button1的weight1剩余宽度占比为1/(12) 1/3所以最终宽度为L1/3*(-L)2/3LButton2的计算类似最终宽度为L2/3(-L)1/3L。 这是在水平方向上的那么在垂直方向上也是这样吗 下面是测试代码和效果 如果是垂直方向那么我们应该改变的是layout_height的属性下面是0dp的显示效果 下面是match_parent的显示效果结论和水平是完全一样的 虽然说我们演示了match_parent的显示效果并说明了原因但是在真正用的时候我们都是设置某一个属性为0dp然后按照权重计算所占百分比。 使用相对布局禁用绝对布局 在开发中我们大部分时候使用的都是线性布局、相对布局和帧布局绝对布局由于适配性极差所以极少使用。 由于各种布局的特点不一样所以不能说哪个布局好用到底应该使用什么布局只能根据实际需求来确定。我们可以使用 LinearLayout 的嵌套实例并结合 “wrap_content” 和 “match_parent”以便构建相当复杂的布局。不过我们无法通过 LinearLayout 精确控制子视图的特殊关系系统会将 LinearLayout 中的视图直接并排列出。 如果我们需要将子视图排列出各种效果而不是一条直线通常更合适的解决方法是使用 RelativeLayout这样就可以根据各组件之间的特殊关系指定布局了。例如我们可以将某个子视图对齐到屏幕左侧同时将另一个视图对齐到屏幕右侧。 下面的代码以官方Demo为例说明。 ?xml version1.0 encodingutf-8? RelativeLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightmatch_parent TextView android:idid/label android:layout_widthmatch_parent android:layout_heightwrap_content android:textType here:/ EditText android:idid/entry android:layout_widthmatch_parent android:layout_heightwrap_content android:layout_belowid/label/ Button android:idid/ok android:layout_widthwrap_content android:layout_heightwrap_content android:layout_belowid/entry android:layout_alignParentRighttrue android:layout_marginLeft10dp android:textOK / Button android:layout_widthwrap_content android:layout_heightwrap_content android:layout_toLeftOfid/ok android:layout_alignTopid/ok android:textCancel / /RelativeLayout   在上面的代码中我们使用了相对布局并且使用alignXXX等属性指定了子控件的位置下面是这种布局方式在应对屏幕变化时的表现 在小尺寸屏幕的显示 在平板的大尺寸上的显示效果 虽然控件的大小由于屏幕尺寸的增加而发生了改变但是我们可以看到由于使用了相对布局所以控件之前的位置关系并没有发生什么变化这说明我们的适配成功了。 使用限定符 使用尺寸限定符 上面所提到的灵活布局或者是相对布局可以为我们带来的优势就只有这么多了。虽然这些布局可以拉伸组件内外的空间以适应各种屏幕但它们不一定能为每种屏幕都提供最佳的用户体验。因此我们的应用不仅仅只实施灵活布局还应该应针对各种屏幕配置提供一些备用布局。 如何做到这一点呢我们可以通过使用配置限定符在运行时根据当前的设备配置自动选择合适的资源了例如根据各种屏幕尺寸选择不同的布局。 很多应用会在较大的屏幕上实施“双面板”模式即在一个面板上显示项目列表而在另一面板上显示对应内容。平板电脑和电视的屏幕已经大到可以同时容纳这两个面板了但手机屏幕就需要分别显示。因此我们可以使用以下文件以便实施这些布局 res/layout/main.xml单面板默认布局 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:orientationvertical android:layout_widthmatch_parent android:layout_heightmatch_parent fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_widthmatch_parent / /LinearLayout   res/layout-large/main.xml双面板布局 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthfill_parent android:layout_heightfill_parent android:orientationhorizontal fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_width400dp android:layout_marginRight10dp/ fragment android:idid/article android:layout_heightfill_parent android:namecom.example.android.newsreader.ArticleFragment android:layout_widthfill_parent / /LinearLayout   请注意第二种布局名称目录中的 large 限定符。系统会在属于较大屏幕例如 7 英寸或更大的平板电脑的设备上选择此布局。系统会在较小的屏幕上选择其他布局无限定符。 使用最小宽度限定符 在版本低于 3.2 的 Android 设备上开发人员遇到的问题之一是“较大”屏幕的尺寸范围该问题会影响戴尔 Streak、早期的 Galaxy Tab 以及大部分 7 英寸平板电脑。即使这些设备的屏幕属于“较大”的尺寸但很多应用可能会针对此类别中的各种设备例如 5 英寸和 7 英寸的设备显示不同的布局。这就是 Android 3.2 版在引入其他限定符的同时引入“最小宽度”限定符的原因。 最小宽度限定符可让您通过指定某个最小宽度以 dp 为单位来定位屏幕。例如标准 7 英寸平板电脑的最小宽度为 600 dp因此如果您要在此类屏幕上的用户界面中使用双面板但在较小的屏幕上只显示列表您可以使用上文中所述的单面板和双面板这两种布局但您应使用 sw600dp 指明双面板布局仅适用于最小宽度为 600 dp 的屏幕而不是使用 large 尺寸限定符。 res/layout/main.xml单面板默认布局 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:orientationvertical android:layout_widthmatch_parent android:layout_heightmatch_parent fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_widthmatch_parent / /LinearLayout     res/layout-sw600dp/main.xml双面板布局 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthfill_parent android:layout_heightfill_parent android:orientationhorizontal fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_width400dp android:layout_marginRight10dp/ fragment android:idid/article android:layout_heightfill_parent android:namecom.example.android.newsreader.ArticleFragment android:layout_widthfill_parent / /LinearLayout     也就是说对于最小宽度大于等于 600 dp 的设备系统会选择 layout-sw600dp/main.xml双面板布局否则系统就会选择 layout/main.xml单面板布局。 但 Android 版本低于 3.2 的设备不支持此技术原因是这些设备无法将 sw600dp 识别为尺寸限定符因此我们仍需使用 large 限定符。这样一来就会有一个名称为 res/layout-large/main.xml 的文件与 res/layout-sw600dp/main.xml 一样。但是没有太大关系我们将马上学习如何避免此类布局文件出现的重复。 使用布局别名 最小宽度限定符仅适用于 Android 3.2 及更高版本。因此如果我们仍需使用与较低版本兼容的概括尺寸范围小、正常、大和特大。例如如果要将用户界面设计成在手机上显示单面板但在 7 英寸平板电脑、电视和其他较大的设备上显示多面板那么我们就需要提供以下文件 res/layout/main.xml: 单面板布局res/layout-large: 多面板布局res/layout-sw600dp: 多面板布局后两个文件是相同的因为其中一个用于和 Android 3.2 设备匹配而另一个则是为使用较低版本 Android 的平板电脑和电视准备的。 要避免平板电脑和电视的文件出现重复以及由此带来的维护问题您可以使用别名文件。例如您可以定义以下布局 res/layout/main.xml单面板布局res/layout/main_twopanes.xml双面板布局然后添加这两个文件 res/values-large/layout.xml: resourcesitem namemain typelayoutlayout/main_twopanes/item /resources     res/values-sw600dp/layout.xml: resourcesitem namemain typelayoutlayout/main_twopanes/item /resources   后两个文件的内容相同但它们并未实际定义布局。它们只是将 main 设置成了 main_twopanes 的别名。由于这些文件包含 large 和 sw600dp 选择器因此无论 Android 版本如何系统都会将这些文件应用到平板电脑和电视上版本低于 3.2 的平板电脑和电视会匹配 large版本高于 3.2 的平板电脑和电视则会匹配 sw600dp。 使用屏幕方向限定符 某些布局会同时支持横向模式和纵向模式但我们可以通过调整优化其中大部分布局的效果。在新闻阅读器示例应用中每种屏幕尺寸和屏幕方向下的布局行为方式如下所示 小屏幕纵向单面板带徽标小屏幕横向单面板带徽标7 英寸平板电脑纵向单面板带操作栏7 英寸平板电脑横向双面板宽带操作栏10 英寸平板电脑纵向双面板窄带操作栏10 英寸平板电脑横向双面板宽带操作栏电视横向双面板宽带操作栏因此这些布局中的每一种都定义在了 res/layout/ 目录下的某个 XML 文件中。为了继续将每个布局分配给各种屏幕配置该应用会使用布局别名将两者相匹配 res/layout/onepane.xml:(单面板) LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:orientationvertical android:layout_widthmatch_parent android:layout_heightmatch_parent fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_widthmatch_parent / /LinearLayout     res/layout/onepane_with_bar.xml:(单面板带操作栏) LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:orientationvertical android:layout_widthmatch_parent android:layout_heightmatch_parent LinearLayout android:layout_widthmatch_parent android:idid/linearLayout1 android:gravitycenter android:layout_height50dp ImageView android:idid/imageView1 android:layout_heightwrap_content android:layout_widthwrap_content android:srcdrawable/logo android:paddingRight30dp android:layout_gravityleft android:layout_weight0 / View android:layout_heightwrap_content android:idid/view1 android:layout_widthwrap_content android:layout_weight1 / Button android:idid/categorybutton android:backgrounddrawable/button_bg android:layout_heightmatch_parent android:layout_weight0 android:layout_width120dp stylestyle/CategoryButtonStyle/ /LinearLayout fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_widthmatch_parent / /LinearLayout     res/layout/twopanes.xml:(双面板宽布局) LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthfill_parent android:layout_heightfill_parent android:orientationhorizontal fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_width400dp android:layout_marginRight10dp/ fragment android:idid/article android:layout_heightfill_parent android:namecom.example.android.newsreader.ArticleFragment android:layout_widthfill_parent / /LinearLayout     res/layout/twopanes_narrow.xml:(双面板窄布局) LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthfill_parent android:layout_heightfill_parent android:orientationhorizontal fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_width200dp android:layout_marginRight10dp/ fragment android:idid/article android:layout_heightfill_parent android:namecom.example.android.newsreader.ArticleFragment android:layout_widthfill_parent / /LinearLayout     既然我们已定义了所有可能的布局那就只需使用配置限定符将正确的布局映射到各种配置即可。 现在只需使用布局别名技术即可做到这一点 res/values/layouts.xml: resourcesitem namemain_layout typelayoutlayout/onepane_with_bar/item bool namehas_two_panesfalse/bool /resources     res/values-sw600dp-land/layouts.xml: resourcesitem namemain_layout typelayoutlayout/twopanes/item bool namehas_two_panestrue/bool /resources     res/values-sw600dp-port/layouts.xml: resourcesitem namemain_layout typelayoutlayout/onepane/item bool namehas_two_panesfalse/bool /resources     res/values-large-land/layouts.xml: resourcesitem namemain_layout typelayoutlayout/twopanes/item bool namehas_two_panestrue/bool /resources     res/values-large-port/layouts.xml: resourcesitem namemain_layout typelayoutlayout/twopanes_narrow/item bool namehas_two_panestrue/bool /resources     使用自动拉伸位图 支持各种屏幕尺寸通常意味着您的图片资源还必须能适应各种尺寸。例如无论要应用到什么形状的按钮上按钮背景都必须能适应。 如果在可以更改尺寸的组件上使用了简单的图片您很快就会发现显示效果多少有些不太理想因为系统会在运行时平均地拉伸或收缩您的图片。解决方法为使用自动拉伸位图这是一种格式特殊的 PNG 文件其中会指明可以拉伸以及不可以拉伸的区域。 .9的制作实际上就是在原图片上添加1px的边界然后按照我们的需求把对应的位置设置成黑色线系统就会根据我们的实际需求进行拉伸。 下图是对.9图的四边的含义的解释左上边代表拉伸区域右下边代表padding box就是间隔区域在下面我们给出一个例子方便大家理解。 先看下面两张图我们理解一下这四条线的含义。 上图和下图的区别就在于右下边的黑线不一样具体的效果的区别看右边的效果图。上图效果图中深蓝色的区域代表内容区域我们可以看到是在正中央的这是因为我们在右下边的是两个点这两个点距离上下左右四个方向的距离就是padding的距离所以深蓝色内容区域在图片正中央我们再看下图由于右下边的黑线是图片长度所以就没有padding从效果图上的表现就是深蓝色区域和图片一样大因此我们可以利用右下边来控制内容与背景图边缘的padding。 如果你还不明白那么我们看下面的效果图我们分别以图一和图二作为背景图下面是效果图。 我们可以看到使用wrap_content属性设置长宽图一比图二的效果大一圈这是为什么呢还记得我上面说的padding吗 这就是padding的效果提现怎么证明呢我们再看下面一张图给图一添加padding0这样背景图设置的padding效果就没了是不是两个一样大了 ok我想你应该明白右下边的黑线的含义了下面我们再看一下左上边的效果。 下面我们只设置了左上边线效果图如下 上面的线没有包住图标下面的线正好包住了图标从右边的效果图应该可以看出差别黑线所在的区域就是拉伸区域上图黑线所在的全是纯色所以图标不变形下面的拉伸区域包裹了图标所以在拉伸的时候就会对图标进行拉伸但是这样就会导致图标变形。注意到下面红线区域了嘛这是系统提示我们的因为这样拉伸不符合要求所以会提示一下。 支持各种屏幕密度 使用非密度制约像素 由于各种屏幕的像素密度都有所不同因此相同数量的像素在不同设备上的实际大小也有所差异这样使用像素定义布局尺寸就会产生问题。因此请务必使用 dp 或 sp 单位指定尺寸。dp 是一种非密度制约像素其尺寸与 160 dpi 像素的实际尺寸相同。sp 也是一种基本单位但它可根据用户的偏好文字大小进行调整即尺度独立性像素因此我们应将该测量单位用于定义文字大小。 例如请使用 dp而非 px指定两个视图间的间距 Button android:layout_widthwrap_contentandroid:layout_heightwrap_content android:textstring/clickme android:layout_marginTop20dp /     请务必使用 sp 指定文字大小 TextView android:layout_widthmatch_parentandroid:layout_heightwrap_content android:textSize20sp /   除了介绍这些最基础的知识之外我们下面再来讨论一下另外一个问题。 经过上面的介绍我们都清楚为了能够规避不同像素密度的陷阱Google推荐使用dp来代替px作为控件长度的度量单位但是我们来看下面的一个场景。 假如我们以Nexus5作为书写代码时查看效果的测试机型Nexus5的总宽度为360dp我们现在需要在水平方向上放置两个按钮一个是150dp左对齐另外一个是200dp右对齐中间留有10dp间隔那么在Nexus5上面的显示效果就是下面这样 但是如果在Nexus S或者是Nexus One运行呢下面是运行结果 可以看到两个按钮发生了重叠。 我们都已经用了dp了为什么会出现这种情况呢 你听我慢慢道来。 虽然说dp可以去除不同像素密度的问题使得1dp在不同像素密度上面的显示效果相同但是还是由于Android屏幕设备的多样性如果使用dp来作为度量单位并不是所有的屏幕的宽度都是相同的dp长度比如说Nexus S和Nexus One属于hdpi屏幕宽度是320dp而Nexus 5属于xxhdpi屏幕宽度是360dpGalaxy Nexus属于xhdpi屏幕宽度是384dpNexus 6 属于xxxhdpi屏幕宽度是410dp。所以说光Google自己一家的产品就已经有这么多的标准而且屏幕宽度和像素密度没有任何关联关系即使我们使用dp在320dp宽度的设备和410dp的设备上还是会有90dp的差别。当然我们尽量使用match_parent和wrap_content尽可能少的用dp来指定控件的具体长宽再结合上权重大部分的情况我们都是可以做到适配的。 但是除了这个方法我们还有没有其他的更彻底的解决方案呢 我们换另外一个思路来思考这个问题。 下面的方案来自Android Day Day Up 一群的【blue-深圳】谢谢他的分享精神 因为分辨率不一样所以不能用px因为屏幕宽度不一样所以要小心的用dp那么我们可不可以用另外一种方法来统一单位不管分辨率是多大屏幕宽度用一个固定的值的单位来统计呢 答案是当然可以。 我们假设手机屏幕的宽度都是320某单位那么我们将一个屏幕宽度的总像素数平均分成320份每一份对应具体的像素就可以了。 具体如何来实现呢我们看下面的代码 import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintWriter;public class MakeXml { private final static String rootPath C:\\Users\\Administrator\\Desktop\\layoutroot\\values-{0}x{1}\\; private final static float dw 320f; private final static float dh 480f; private final static String WTemplate dimen name\x{0}\{1}px/dimen\n; private final static String HTemplate dimen name\y{0}\{1}px/dimen\n; public static void main(String[] args) { makeString(320, 480); makeString(480,800); makeString(480, 854); makeString(540, 960); makeString(600, 1024); makeString(720, 1184); makeString(720, 1196); makeString(720, 1280); makeString(768, 1024); makeString(800, 1280); makeString(1080, 1812); makeString(1080, 1920); makeString(1440, 2560); } public static void makeString(int w, int h) { StringBuffer sb new StringBuffer(); sb.append(?xml version\1.0\ encoding\utf-8\?\n); sb.append(resources); float cellw w / dw; for (int i 1; i 320; i) { sb.append(WTemplate.replace({0}, i ).replace({1}, change(cellw * i) )); } sb.append(WTemplate.replace({0}, 320).replace({1}, w )); sb.append(/resources); StringBuffer sb2 new StringBuffer(); sb2.append(?xml version\1.0\ encoding\utf-8\?\n); sb2.append(resources); float cellh h / dh; for (int i 1; i 480; i) { sb2.append(HTemplate.replace({0}, i ).replace({1}, change(cellh * i) )); } sb2.append(HTemplate.replace({0}, 480).replace({1}, h )); sb2.append(/resources); String path rootPath.replace({0}, h ).replace({1}, w ); File rootFile new File(path); if (!rootFile.exists()) { rootFile.mkdirs(); } File layxFile new File(path lay_x.xml); File layyFile new File(path lay_y.xml); try { PrintWriter pw new PrintWriter(new FileOutputStream(layxFile)); pw.print(sb.toString()); pw.close(); pw new PrintWriter(new FileOutputStream(layyFile)); pw.print(sb2.toString()); pw.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } } public static float change(float a) { int temp (int) (a * 100); return temp / 100f; } }     代码应该很好懂我们将一个屏幕宽度分为320份高度480份然后按照实际像素对每一个单位进行复制放在对应values-widthxheight文件夹下面的lax.xml和lay.xml里面这样就可以统一所有你想要的分辨率的单位了下面是生成的一个320*480分辨率的文件因为宽高分割之后总分数和像素数相同所以x1就是1px以此类推 ?xml version1.0 encodingutf-8? resourcesdimen namex11.0px/dimen dimen namex22.0px/dimen dimen namex33.0px/dimen dimen namex44.0px/dimen dimen namex55.0px/dimen dimen namex66.0px/dimen dimen namex77.0px/dimen dimen namex88.0px/dimen dimen namex99.0px/dimen dimen namex1010.0px/dimen ...省略好多行 dimen namex300300.0px/dimen dimen namex301301.0px/dimen dimen namex302302.0px/dimen dimen namex303303.0px/dimen dimen namex304304.0px/dimen dimen namex305305.0px/dimen dimen namex306306.0px/dimen dimen namex307307.0px/dimen dimen namex308308.0px/dimen dimen namex309309.0px/dimen dimen namex310310.0px/dimen dimen namex311311.0px/dimen dimen namex312312.0px/dimen dimen namex313313.0px/dimen dimen namex314314.0px/dimen dimen namex315315.0px/dimen dimen namex316316.0px/dimen dimen namex317317.0px/dimen dimen namex318318.0px/dimen dimen namex319319.0px/dimen dimen namex320320px/dimen /resources     那么1080*1960分辨率下是什么样子呢我们可以看下由于1080和320是3.37倍的关系所以x13.37px ?xml version1.0 encodingutf-8? resourcesdimen namex13.37px/dimen dimen namex26.75px/dimen dimen namex310.12px/dimen dimen namex413.5px/dimen dimen namex516.87px/dimen dimen namex620.25px/dimen dimen namex723.62px/dimen dimen namex827.0px/dimen dimen namex930.37px/dimen dimen namex1033.75px/dimen ...省略好多行 dimen namex3001012.5px/dimen dimen namex3011015.87px/dimen dimen namex3021019.25px/dimen dimen namex3031022.62px/dimen dimen namex3041026.0px/dimen dimen namex3051029.37px/dimen dimen namex3061032.75px/dimen dimen namex3071036.12px/dimen dimen namex3081039.5px/dimen dimen namex3091042.87px/dimen dimen namex3101046.25px/dimen dimen namex3111049.62px/dimen dimen namex3121053.0px/dimen dimen namex3131056.37px/dimen dimen namex3141059.75px/dimen dimen namex3151063.12px/dimen dimen namex3161066.5px/dimen dimen namex3171069.87px/dimen dimen namex3181073.25px/dimen dimen namex3191076.62px/dimen dimen namex3201080px/dimen /resources     无论在什么分辨率下x320都是代表屏幕宽度y480都是代表屏幕高度。 那么我们应该如何使用呢 首先我们要把生成的所有values文件夹放到res目录下当设计师把UI高清设计图给你之后你就可以根据设计图上的尺寸以某一个分辨率的机型为基础找到对应像素数的单位然后设置给控件即可。 下图还是两个Button不同的是我们把单位换成了我们在values文件夹下dimen的值这样在你指定的分辨率下不管宽度是320dp、360dp还是410dp就都可以完全适配了。 但是还是有个问题为什么下面的三个没有适配呢 这是因为由于在生成的values文件夹里没有对应的分辨率其实一开始是报错的因为默认的values没有对应dimen所以我只能在默认values里面也创建对应文件但是里面的数据却不好处理因为不知道分辨率我只好默认为x11dp保证尽量兼容。这也是这个解决方案的几个弊端对于没有生成对应分辨率文件的手机会使用默认values文件夹如果默认文件夹没有就会出现问题。 所以说这个方案虽然是一劳永逸但是由于实际上还是使用的px作为长度的度量单位所以多少和google的要求有所背离不好说以后会不会出现什么不可预测的问题。其次如果要使用这个方案你必须尽可能多的包含所有的分辨率因为这个是使用这个方案的基础如果有分辨率缺少会造成显示效果很差甚至出错的风险而这又势必会增加软件包的大小和维护的难度所以大家自己斟酌择优使用。 更多信息可参考鸿洋的新文章Android 屏幕适配方案 提供备用位图 由于 Android 可在具有各种屏幕密度的设备上运行因此我们提供的位图资源应始终可以满足各类普遍密度范围的要求低密度、中等密度、高密度以及超高密度。这将有助于我们的图片在所有屏幕密度上都能得到出色的质量和效果。 要生成这些图片我们应先提取矢量格式的原始资源然后根据以下尺寸范围针对各密度生成相应的图片。 xhdpi2.0hdpi1.5mdpi1.0最低要求ldpi0.75也就是说如果我们为 xhdpi 设备生成了 200x200 px尺寸的图片就应该使用同一资源为 hdpi、mdpi 和 ldpi 设备分别生成 150x150、100x100 和 75x75 尺寸的图片。 然后将生成的图片文件放在 res/ 下的相应子目录中(mdpi、hdpi、xhdpi、xxhdpi)系统就会根据运行您应用的设备的屏幕密度自动选择合适的图片。 这样一来只要我们引用 drawable/id系统都能根据相应屏幕的 dpi 选取合适的位图。 还记得我们上面提到的图标设计尺寸吗和这个其实是一个意思。 但是还有个问题需要注意下如果是.9图或者是不需要多个分辨率的图片就放在drawable文件夹即可对应分辨率的图片要正确的放在合适的文件夹否则会造成图片拉伸等问题。 实施自适应用户界面流程 前面我们介绍过如何根据设备特点显示恰当的布局但是这样做会使得用户界面流程可能会有所不同。例如如果应用处于双面板模式下点击左侧面板上的项即可直接在右侧面板上显示相关内容而如果该应用处于单面板模式下点击相关的内容应该跳转到另外一个Activity进行后续的处理。所以我们应该按照下面的流程一步步的完成自适应界面的实现。 确定当前布局 由于每种布局的实施都会稍有不同因此我们需要先确定当前向用户显示的布局。例如我们可以先了解用户所处的是“单面板”模式还是“双面板”模式。要做到这一点可以通过查询指定视图是否存在以及是否已显示出来。 public class NewsReaderActivity extends FragmentActivity { boolean mIsDualPane; Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); View articleView findViewById(R.id.article); mIsDualPane articleView ! null articleView.getVisibility() View.VISIBLE; } }     请注意这段代码用于查询“报道”面板是否可用与针对具体布局的硬编码查询相比这段代码的灵活性要大得多。 再举一个适应各种组件的存在情况的方法示例在对这些组件执行操作前先查看它们是否可用。例如新闻阅读器示例应用中有一个用于打开菜单的按钮但只有在版本低于 3.0 的 Android 上运行该应用时这个按钮才会存在因为 API 级别 11 或更高级别中的 ActionBar 已取代了该按钮的功能。因此您可以使用以下代码为此按钮添加事件侦听器 Button catButton (Button) findViewById(R.id.categorybutton); OnClickListener listener /* create your listener here */; if (catButton ! null) { catButton.setOnClickListener(listener); }       根据当前布局做出响应 有些操作可能会因当前的具体布局而产生不同的结果。例如在新闻阅读器示例中如果用户界面处于双面板模式下那么点击标题列表中的标题就会在右侧面板中打开相应报道但如果用户界面处于单面板模式下那么上述操作就会启动一个独立活动 Override public void onHeadlineSelected(int index) {mArtIndex index; if (mIsDualPane) { /* display article on the right pane */ mArticleFragment.displayArticle(mCurrentCat.getArticle(index)); } else { /* start a separate activity */ Intent intent new Intent(this, ArticleActivity.class); intent.putExtra(catIndex, mCatIndex); intent.putExtra(artIndex, index); startActivity(intent); } }     同样如果该应用处于双面板模式下就应设置带导航标签的操作栏但如果该应用处于单面板模式下就应使用下拉菜单设置导航栏。因此我们的代码还应确定哪种情况比较合适 final String CATEGORIES[] { 热门报道, 政治, 经济, Technology }; public void onCreate(Bundle savedInstanceState) { .... if (mIsDualPane) { /* use tabs for navigation */ actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_TABS); int i; for (i 0; i CATEGORIES.length; i) { actionBar.addTab(actionBar.newTab().setText( CATEGORIES[i]).setTabListener(handler)); } actionBar.setSelectedNavigationItem(selTab); } else { /* use list navigation (spinner) */ actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_LIST); SpinnerAdapter adap new ArrayAdapter(this, R.layout.headline_item, CATEGORIES); actionBar.setListNavigationCallbacks(adap, handler); } }     重复使用其他活动中的片段 多屏幕设计中的重复模式是指对于某些屏幕配置已实施界面的一部分会用作面板但对于其他配置这部分就会以独立活动的形式存在。例如在新闻阅读器示例中对于较大的屏幕新闻报道文本会显示在右侧面板中但对于较小的屏幕这些文本就会以独立活动的形式存在。 在类似情况下通常可以在多个活动中重复使用相同的 Fragment 子类以避免代码重复。例如在双面板布局中使用了 ArticleFragment LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthfill_parent android:layout_heightfill_parent android:orientationhorizontal fragment android:idid/headlines android:layout_heightfill_parent android:namecom.example.android.newsreader.HeadlinesFragment android:layout_width400dp android:layout_marginRight10dp/ fragment android:idid/article android:layout_heightfill_parent android:namecom.example.android.newsreader.ArticleFragment android:layout_widthfill_parent / /LinearLayout     然后又在小屏幕的Activity布局中重复使用了它 ArticleFragment frag new ArticleFragment(); getSupportFragmentManager().beginTransaction().add(android.R.id.content, frag).commit();     当然这与在 XML 布局中声明片段的效果是一样的但在这种情况下却没必要使用 XML 布局因为报道片段是此活动中的唯一组件。 请务必在设计片段时注意不要针对具体活动创建强耦合。要做到这一点通常可以定义一个接口该接口概括了相关片段与其主活动交互所需的全部方式然后让主活动实施该界面 例如新闻阅读器应用的 HeadlinesFragment 会精确执行以下代码 public class HeadlinesFragment extends ListFragment { ... OnHeadlineSelectedListener mHeadlineSelectedListener null; /* Must be implemented by host activity */ public interface OnHeadlineSelectedListener { public void onHeadlineSelected(int index); } ... public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener listener) { mHeadlineSelectedListener listener; } }     然后如果用户选择某个标题相关片段就会通知由主活动指定的侦听器而不是通知某个硬编码的具体活动 public class HeadlinesFragment extends ListFragment { ... Override public void onItemClick(AdapterView? parent, View view, int position, long id) { if (null ! mHeadlineSelectedListener) { mHeadlineSelectedListener.onHeadlineSelected(position); } } ... }     除此之外我们还可以使用第三方框架比如说使用“订阅-发布”模式的EventBus来更多的优化组件之间的通信减少耦合。 处理屏幕配置变化 如果我们使用独立Activity实施界面的独立部分那么请注意我们可能需要对特定配置变化例如屏幕方向的变化做出响应以便保持界面的一致性。 例如在运行 Android 3.0 或更高版本的标准 7 英寸平板电脑上如果新闻阅读器示例应用运行在纵向模式下就会在使用独立活动显示新闻报道但如果该应用运行在横向模式下就会使用双面板布局。 也就是说如果用户处于纵向模式下且屏幕上显示的是用于阅读报道的活动那么就需要在检测到屏幕方向变化变成横向模式后执行相应操作即停止上述活动并返回主活动以便在双面板布局中显示相关内容 public class ArticleActivity extends FragmentActivity { int mCatIndex, mArtIndex; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCatIndex getIntent().getExtras().getInt(catIndex, 0); mArtIndex getIntent().getExtras().getInt(artIndex, 0); // If should be in two-pane mode, finish to return to main activity if (getResources().getBoolean(R.bool.has_two_panes)) { finish(); return; } ... }     通过上面几个步骤我们就完全可以建立一个可以根据用户界面配置进行自适应的App了。 最佳实践 关于高清设计图尺寸 Google官方给出的高清设计图尺寸有两种方案一种是以mdpi设计然后对应放大得到更高分辨率的图片另外一种则是以高分辨率作为设计大小然后按照倍数对应缩小到小分辨率的图片。 根据经验我更推荐第二种方法因为小分辨率在生成高分辨率图片的时候会出现像素丢失我不知道是不是有方法可以阻止这种情况发生。 而分辨率可以以1280*720或者是1960*1080作为主要分辨率进行设计。 ImageView的ScaleType属性 设置不同的ScaleType会得到不同的显示效果一般情况下设置为centerCrop能获得较好的适配效果。 动态设置 有一些情况下我们需要动态的设置控件大小或者是位置比如说popwindow的显示位置和偏移量等这个时候我们可以动态的获取当前的屏幕属性然后设置合适的数值 public class ScreenSizeUtil {public static int getScreenWidth(Activity activity) { return activity.getWindowManager().getDefaultDisplay().getWidth(); } public static int getScreenHeight(Activity activity) { return activity.getWindowManager().getDefaultDisplay().getHeight(); } }     更多参考资料 chan奕迅(设计师角度)友盟移动指数(最新的移动设备统计信息)手机屏幕信息大全转载于:https://www.cnblogs.com/wytiger/p/5204795.html
http://www.sadfv.cn/news/122012/

相关文章:

  • 海南爱心扶贫网站是哪个公司做的常德做网站公司哪家好
  • 在线销售型网站产品wordpress 栏目投稿
  • 深圳场站建设发展有限公司江门企业网站模板建站
  • 企业网站免费建设工具网站关键词设置
  • 12306网站开发笑话泰安信息港官网
  • 做网站的技术盏wap建站工具
  • 免费的建手机网站建设银行信用卡进度查询官方网站
  • 天津 企业网站建设学习做网站教程
  • 关于怎么做网站国外网站界面
  • 企业网站怎么做连接推广网站有哪些方式
  • 怎么做网站评论教育培训类网站开发
  • 网站开发的源码垫江网站建设报价
  • 查询网站到期时间哔哩哔哩网页版打开
  • 电商网站改版思路seo查询网址
  • 怎样建企业网站平台开发软件
  • 网站建设服务器选择网络运营工程师
  • 个人备案网站可以做淘宝客吗单页面优化的重点
  • 游戏网站开发有限公司网页主题设计思路及制作步骤
  • 门户网站的建设要求wordpress关键词内链图片
  • 如何提高网站打开速度七个2wordpress
  • 动易官方网站百度网站开发基于什么语言
  • 网站建设类公大男人看的视频
  • 美丽定制 网站模板百度关键词流量查询
  • 企业网站的建立目的和特点是什么优质网站有哪些
  • 织梦调用网站类型网站优化有哪些方法
  • 电子商务网站建设实训目的潮州汕头
  • 茂名做网站的公司香山网站建设
  • 旅游网站建设的经济评价数据库修改网站管理员密码
  • 专题文档dede企业网站建设医院网站开发违法吗
  • 为什么原网站建设公司不愿意透露域名管理权限给客户响应式网站怎么写