array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 屏幕适配升级之今日头条总结 - 爱码网

因为Android系统的碎片化,手机分辨率和尺寸的多样化所以开发中经常需要进行屏幕适配。

看了今日头条的技术博客之屏幕适配觉得很NB,看完之后,学到很多,以下作为基础部分回顾以及对适配方案进行总结 这是今日头条传送门

 

回顾一下基本知识:

屏幕尺寸 是指屏幕对角线的长度

分辨率 是指屏幕横向像素的数量 * 纵向像素的数量。

在进行屏幕适配的时候需要注意几个单位:

dp    (设备无关的像素)在Android中是长度的单位

px  (像素)一个像素表示屏幕上的一个点

dpi (像素密度)每英寸内的像素个数。

density (屏幕密度)

Android中的dp在渲染前会将dp转为px,计算公式:

px = density * dp;

density = dpi / 160;

px = dp * (dpi / 160);

 

Android drawable

drawable-ldpi (dpi=120, density=0.75)

drawable-mdpi (dpi=160, density=1)

drawable-hdpi (dpi=240, density=1.5)

drawable-xhdpi (dpi=320, density=2)

drawable-xxhdpi (dpi=480, density=3)

 

直接看图更直观(网络截图,非自画

屏幕适配升级之今日头条总结

这是一个勾股定理计算方式哈哈,比如一个手机分辨率为1920 * 1080尺寸为5 那么计算结果,像素密度dpi就是 440。

 

在屏幕适配中遇到的问题是,比如UI小姐姐给我们切的图是按照屏幕宽度360dp来设计的,经过计算手机屏幕实际上是

(1080 /( 440 / 160 )= 392.7dp),所以实际上屏幕宽度比设计图要宽度要大。

 

常见的屏幕分辨率适配有几种吧:

1 在屏幕适配中使用dp而不使用px,dp可以保证在不同屏幕像素密度的设备显示相同效果,所以在布局使用dp作为单位。还有,在布局设置的任何单位,在页面渲染的时候,系统最终都会转化为px。

缺点屏幕尺寸相差过大,无法保证相同。

 

2 切多套图适配,针对不同机型使用不同的资源文件,这样会使UI设计人员工作量加大,同时造成资源文件过多,apk体积变大。

 

3 .9图片适配,.9图片作为特殊的png图片,可以不同机型进行适配。缺点是还要单独设计制作.9图片。

 

4 布局适配,尽量使用wrap_content,match_parent以及权重weight,使用相对布局,不要使用绝对布局。缺点无法保证所有绘图部分都是这样的。

 

5 使用分辨率适配,根据不同values下分辨率进行适配,应用会自动寻找相适应的分辨率。也叫宽高限定符如下,在资源文件下生成不同的分辨率资源,设计不同的尺寸,然后在布局文件引入对应的dimens,缺点是要收集市场上所有的机型分辨率,比较繁琐

屏幕适配升级之今日头条总结

 

6 代码适配,比如获取LayoutParams的对象动态设置宽高,缺点需要计算,比较麻烦。

 

这里给出几位大佬的适配方案 拉丁吴大佬 

鸿洋大神:

 https://github.com/hongyangAndroid/AndroidAutoLayout

 

今日头条会根据公式算出density(也可以这样理解density就是1dp占用当前设备多少像素):

当前设备屏幕总宽度(单位为像素)/ 设计图总宽度(单位为 dp) = density

 

今日头条的做法就是强行将不同分辨率的手机的宽度dp修改为统一的值。

屏幕的总 px 宽度 / density = 屏幕的总 dp 宽度

 

比如UI设计师给的设计图的宽度是360dp,那么对于任何不同分辨率的手机设备(不管是1080 * 720 或者是 1920 * 1080),开发同学总是根据公式算出

density(手机屏幕宽度像素px / 360dp = density)然后动态修改不同分辨率手机的density值,从而保证不同分辨率手机的宽度dp具有一个统一的值比如360dp。

 

今日头条的开发工程师真是厉害,玩的太溜了o( ̄▽ ̄)d

引入头条:{ density 是 DisplayMetrics 中的成员变量,而 DisplayMetrics 实例通过 Resources#getDisplayMetrics 可以获得,

而Resouces通过Activity或者Application的Context获得。

 

因为布局文件最终会将dp转化为px,实现方式是通过调用 

TypedValue#applyDimension

(int unit, float value, DisplayMetrics metrics) 来进行转换 }

看里面的源码:屏幕适配升级之今日头条总结

系统就是根据上面的方法,将项目中任何设置的单位,最终在渲染的时候都会转化为px的。而常用的公式px = dp(dpi / 160) 就是根据上面的方法来的,

比如 density = dpi / 160 ,  px = value * density,而density是DisplayMetrics中的一个变量。 

 

这个时候做法就是,如果保证屏幕的宽度和设计图上的宽度保持一致的话,那我们在布局时就可以直接按照设计图上的尺寸填写 dp 值就ok了。

今日头条原理就是把屏幕的实际宽度转换为设计图上的宽度

 

今日头条的适配方式只能以屏幕中高度或者宽度其中一个作为基准进行适配,为什么不能同时进行适配呢?因为市场上Android机型太多了,基本上不同机型的屏幕宽高比都不一致,尤其现在各大厂商都主打 全面屏,问题更多了,以宽或者高其中一个作为基准进行适合配,可以有效避免布局在宽高比不一致的屏幕上发生变形。

 

今日头条的实现方式:

根据公式算出density值,然后将计算好的density值传入下面的方法中,这个方法需要在Activity的onCreate方法中调用,然后修改系统的density值:

屏幕适配升级之今日头条总结

 

原理,实现方式总结完了,不由感叹奇思妙想的今日头条的工程师,并且有好几位大佬都很力挺,比如 blanj大神,并且在今日头条基础上做了封装和完善,感兴趣的同学可以看一下  

https://juejin.im/post/5b6250bee51d451918537021#heading-5

 

大佬们也分析的今日头条适配方案的优缺点,这里总结一下:

优点:

1 使用成本低,操作简单,在页面布局的时候不需要额外的代码和操作。

2 这种方式和自己项目没有耦合吧,并且使用的Android官方的API。

3 适配所有控件,只需要修改density值,项目中所有的控件都能使用。

4 比较稳定,不存在性能消耗。

 

缺点是对老项目不够兼容,系统的density值改变后,那么整个布局的实际尺寸都会改变,在老项目中,以前的布局方式都要重新按照设计图进行修改。

 

大佬们还推荐更完美的适配方案,那就是拉丁吴大神推荐的smallestWidth适配,感兴趣的同学可以看一下

https://github.com/ladingwu/dimens_sw

相关文章: