Neil's blog

Let's start from here


  • 首页

  • 归档

  • 标签

  • 关于

Android屏幕适配解决方案(1)

发表于 2017-07-20 |

首先科普一下涉及到的概念

屏幕尺寸定义:

屏幕对角线的尺寸,单位是英寸(1英寸=2.54cm)。

屏幕尺寸分为物理尺寸和显示分辨率两个部分。物理尺寸是指屏幕的实际大小;屏幕分辨率即把LCD格数(单位是点[dot] )除以屏幕面积得到的就是屏幕分辨率,这个指标是决定画面好坏的最大因素。

屏幕分辨率

屏幕分辨率是指屏幕显示的分辨率。

  • 屏幕分辨率确定计算机屏幕上显示多少信息的设置,以水平和垂直像素来衡量。屏幕分辨率低时(例如 640 x 480),在屏幕上显示的像素少,但尺寸比较大。屏幕分辨率高时(例如 1600 x 1200),在屏幕上显示的像素多,但尺寸比较小。

  • 显示分辨率就是屏幕上显示的像素个数,分辨率160×128的意思是水平方向含有像素数为160个,垂直方向像素数128个。屏幕尺寸一样的情况下,分辨率越高,显示效果就越精细和细腻。

  • 单位:px(pixel),1px=1像素点

  • Android手机常见的分辨率:320x480、480x800、720x1280、1080x1920

像素密度
  • 像素密度,即每英寸屏幕所拥有的像素数,像素密度越大,显示画面细节就越丰富。
      像素密度=√{(长度像素数^2+宽度像素数^2)}/ 屏幕尺寸
      注:屏幕尺寸单位为英寸 例:分辨率为1280*720 屏幕宽度为6英寸 计算所得像素密度约等于245   
  • 单位:dpi(dots per ich),假设设备内每英寸有160个像素,那么该设备的屏幕像素密度=160dpi

  • 安卓手机对于每类手机屏幕大小都有一个相应的屏幕像素密度:

密度类型 代表的分辨率(px) 屏幕像素密度(dpi)
低密度(ldpi) 240x320 120
中密度(mdpi) 320x480 160
高密度(hdpi) 480x800 240
超高密度(xhdpi) 720x1280 320
超超高密度(xxhdpi) 1080x1920 480
密度无关像素

指一个抽象意义上的像素,程序用它来定义界面元素。它作为一个与实际密度无关的单位,帮助程序员构建一个布局方案(界面元素的宽度,高度,位置)。

一个与密度无关的像素,在逻辑尺寸上,与一个位于像素密度为160DPI的屏幕上的像素是一致的,这也是Android平台所假定的默认显示设备。在运行的时候,平台会以目标屏幕的密度作为基准,“透明地”处理所有需要的DIP缩放操作。要把密度无关像素转换为屏幕像素,可以用这样一个简单的公式:pixels = dips * (density / 160)。举个例子,在DPI为240的屏幕上,1个DIP等于1.5个物理像素。我们强烈推荐你用DIP来定义你程序的界面布局,因为这样可以保证你的 UI在各种分辨率的屏幕上都可以正常显示。

dip到pixel转化
Resources r = getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, r.getDisplayMetrics());

这样再绘图时候在不同分辨率下,pixel的值是不同的。

dp与px的转换
密度类型 代表的分辨率(px) 屏幕密度(dpi) 换算(px/dp) 比例
低密度(ldpi) 240x320 120 1dp=0.75px 3
中密度(mdpi) 320x480 160 1dp=1px 4
高密度(hdpi) 480x800 240 1dp=1.5px 6
超高密度(xhdpi) 720x1280 320 1dp=2px 8
超超高密度(xxhdpi) 1080x1920 480 1dp=3px 12

使得某一元素在Android不同尺寸、不同分辨率的手机上具备相同的显示效果;使得布局、布局组件自适应屏幕尺寸;
根据屏幕的配置来加载相应的UI布局、用户界面流程

设计模式之路(4)装饰者模式

发表于 2017-07-19 |

一、定义

装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

二、特性

  1. 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。
  2. 装饰对象包含一个真实对象的引用(reference)
  3. 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。
  4. 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

三、结构

“装饰者”

  1. 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
  2. 具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
  3. 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
  4. 具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。

举个栗子:

(1)在Java设计中

“Java装饰者”

(2)在Android中

“Android装饰者”

四、小结

装饰者模式和代理模式有点类似,很多时候需要仔细辨别,容易混淆,倒不是说会把代理模式看成装饰者模式,而是会把装饰者模式看作代理模式。区分一下,装饰者模式的目的是透明地为客户端对象扩展功能,是继承关系的一种替代方案,而代理模式则是给一个对象提供一个代理对象,并由代理对象来控制对原有对象的引用。装饰者模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,但不对对象本身的功能进行增强。
同时有几个要点需要提一下:

  • 继承属于扩展形式之一,但不一定是达到弹性设计的最佳方案;
  • 在我们的设计,应该尽量对修改关闭,对扩展开发,无需修改现有代码;
  • 组合和委托可用于在运行时动态加上新的行为;
  • 装饰者可以在被装饰者行为的前后根据实际情况加上自己的行为,必要时也可以将被装饰者行为给替换掉;
  • 可以用无数个装饰者包装一个组件,也就是说,装饰者 A 包装了被装饰者 B ,装饰者 C 再包装装饰者 A,根据实际情况这种行为可以累加到多层,通俗讲就是套上多层外壳;
  • 同时,被装饰者也可以存在多个,也就是说 ConcreteComponent 这个角色也可以是多个的。
  • 装饰者模式的优点就是它的特点:可以在运行时动态,透明的为一个组件扩展功能,比继承更加灵活;
  • 缺点也很明显:它会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

设计模式之路(3)开放-封闭原则

发表于 2017-07-18 |

一、具体解释

开放-封闭原则,是说软件实体(类、模块】函数等等)应该可以扩展,但是不可以修改。

也就是,对于扩展是开放的(Open for extension)
对于更改是封闭的(Closed for modification)

二、核心思想

关于开放封闭原则,其核心的思想是:

软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

因此,开放封闭原则主要体现在两个方面:

  • 对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。

  • 对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

设计模式之路(2)单一职责原则

发表于 2017-07-18 |

一、单一职责原则基本定义

Single Responsibility Principle,缩写是SRP。

定义:There should never be more than one reason for a class to change.

即单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小。

单一职责原则定义如下: 单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。

二、由来

SRP这一概念,由Robot C. Martin在其广泛流行的经典著作《Agile Software Development, Principles, Patterns, and Practices》中的面向对象设计原则部分引入。此原则有两个约束:

  • 职责:什么是职责?我之前认为是一个类要实现的功能,或者提供的服务,从面向对象的角度说是内聚性。从这个角度去理解也可以,但是,功能的大小怎么定义是个难题,什么样的功能放在一起是好的内聚也不好定义。我们知道,面向对象设计更多考虑变化因素可能导致系统的改变,从而提供更灵活应变的设计。所以Robert C. Martin从变化这个角度对职责的定义为:“变化的原因(a reason for change)”,理解为,如果你能想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。

  • 单一:只有一个引起类改变的原因

在Martin的书中分析单一职责带来的好处是:

  • 可以分离变化
  • 减少改动
  • 减少不必要的依赖,从而在发生变化时减少设计所遭受的破坏。

但更多的是从类和接口的角度去分析。然而SRP对每一个程序模块都是适用的,比如小到代码块,函数,大到包级别,组件级别。

三、小结

SRP是一把双刃剑,如果做到极端,没有合理的权衡,对于类来说就有可能形成爆炸。类爆炸的可能性有,职责没有划分清楚而形成过多的类;因为业务的需要,需求的复杂性带来的。不论其产生的原因,过多的类,如果没有好的组织方式,杂乱无章,势必带来维护的复杂性。所谓维护的复杂性,在于代码的可读性,以及重构的高成本。一种可行的解决方案就是利用模式来管理,定义清晰的层次结构。比如利用工厂,模板方法等等。

总结起来,对于SRP,正如Robert C. Martin所说,是一起面向对象设计中最简单的原则之一,也是最难正确应用之一。它是其它原则的基础,比如OCP(Open for extension, Close for modification)。但是,万变不离其宗,本质是抽象变化,解除耦合,让设计出来的系统可读性好,可维护性好,可扩展性好。合理的职责划定带来清晰代码单元结构,如果设计不合理则适得其反,导致代码难以读懂,维护成本增加。

设计模式之路(1)-简单工厂模式

发表于 2017-07-17 |

如果对面向对象还不太熟悉,建议先把面向对象的概念过一遍比较好。


一、简单工厂模式的概念

简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。

简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。

简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。

show me code~

举个栗子:

抽象产品–汽车,汽车有很多品牌:Audi、Benz、BMW···

现在有一个客户想开Benz品牌的车,那么最直接的做法就是创建Benz汽车的实例,然后开走~

Benz benz = new Benz();
benz.addGPS();
benz.addRecodes();
benz.addWheels();
benz.drive();

那么再来一个客户,想开Audi品牌的车,那么我们和之前一样,

Audi audi = new Audi();
audi.addGPS();
audi.addRecodes();
audi.addWheels();
audi.drive();

问题就出现了,客户和汽车的创建耦合在一起了,客户是不需要知道的创建的细节的。

所以为了降低耦合,就可以把这些都放到工厂里面去做,客户只需要告诉工厂汽车的品牌和型号就可以了,所有细节交给工厂完成就可以了。这就是简单工厂模式。

工厂类:

public class CarFactory{
    public Benz createBenz(int type){
        switch(type){
            case 200 :
                return new Benz200();
                break;
            case 260 :
                return new Benz260();
                break;
            case 300 :
                return new Benz300();
                break;
            default:
                break;
        }
    }
}

客户类:

public class Customer{
    public static viod main(String[] args){
        CarFactory carFactory = new CarFactory();
        Benz benz200 = carFactory.createBenz(200);//客户定制车型号
        benz200.drive();//客户开走
    }
}

二、简单工厂模式中的几个角色

在简单工厂模式中包含如下几个角色:

  • Factory(工厂角色):工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法factoryMethod(),它的返回类型为抽象产品类型Product。

  • Product(抽象产品角色):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。

  • ConcreteProduct(具体产品角色):它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。

在简单工厂模式中,客户端通过工厂类来创建一个产品类的实例,而无须直接使用new关键字来创建对象,它是工厂模式家族中最简单的一员。

1…101112…14
Neil Liu

Neil Liu

优秀不够,你是否无可替代

68 日志
25 标签
GitHub
© 2019 Neil Liu
由 Hexo 强力驱动
主题 - NexT.Muse