赞
踩
面试问你屏幕适配,那么你要知道为什么Android要做屏幕适配,因为Android是开源的, 各大厂商不仅可以对软件定制,还可以对硬件定制,这样就造成市场上不同分辨率的手机超多,现在估计得有几万或者几十万种,这就导致android设备的碎片化很严重。所以还是做ios很辛福啊,下面对一些概念弄清楚
屏幕尺寸:指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米
屏幕分辨率:是指横纵上的像素点 单位是px 1px = 1个像素点 一般是以纵向像素*横向像素 比如1920*1080 一个屏幕分辨率越高 显示效果就越好
屏幕像素密度:是指每英寸上的像素点数 单位是dpi 是dot per inch 的缩写,屏幕像素密度与屏幕尺寸以及屏幕分辨率有关
以Google的Nexus5为例,它的分辨率是1920*1080 它的屏幕尺寸是4.95inch 屏幕像素密度是445 这是怎么计算出来的呢?
1920*1920+1080*1080这值是4852800 然后开根号再除以4.95就得到是445.03175153177745
像素:构成图像的最小单位 美工或者设计师使用
dip:density independent pixels 是指密度 与像素无关以160dpi为基准,1dip = 1px 和dp一样
加入有二个设备 一个480*320 密度是160dpi. 另外一台是800*480像素密度是240dpi
比如你要在这二个屏幕上要TextView的宽度充满横屏除了使用match_parent还可以使用如下:
我们知道480*320 它的宽度是320px,它是以160dpi为基准的,1px = 1dip 那么它的宽度就是320px就可以 但是在800*480也就是说它的宽度是480px,该如何计算呢?这个也很简单,240/160=1/x; 求这x是多少1.5 相当于1dp = 1.5px 那么它的宽度就是320*1.5 其实这就是我们做屏幕适配使用到的核心技术,想要适配所有手机都是这么适配的。
我们在创建Android项目的时候 系统会帮助我们生成
drawable_mdpi
drawable_hdpi
drawable_xdpi
drawable_xxdpi
drawable_xxxdpi
对应的密度如下:
上面是讲了基本的概念, 下面谈谈如何去适配?
第一种方案:限定符适配
分辨率限定符 drawable-hdpi drawable-xdpi drawable-xxdpi
尺寸限定符layout-small layout-large
最小宽度限定符:values-sw360dp values-sw384dp
屏幕方向限定符:layout_port layout-land
这种方案几乎不用,除非在一些很小公司 做出来的app没啥人用, 大点的额公司肯定不用这套方案,比如我一张图片要放在不同的分辨率下 不但给美工同事添加了工作量,app打包后体积一定会增大,维护起来很麻烦。
第二种方案:自定义像素适配
这种适配目前是最好的,几乎能适配市面上所有的适配 当初在上面公司 交给test in 一个三方的测试公司, 测试了600多设备 都没出现问题,所以这种很靠谱
实现方案:以美工的设计尺寸为原始尺寸,根据不同设备的密度 计算出宽和高
代码如下:
- public class UIAdapter {
- private static volatile UIAdapter instance = null;
- //设计师的参考尺寸
- private static final float defaultWidth = 1080;
- private static final float defaultHeight = 1920;
- //屏幕的真实尺寸
- private int screenWidth;
- private int screenHeight;
- private UIAdapter(){
-
- }
- public static UIAdapter getInstance(){
- if(null==instance){
- synchronized (UIAdapter.class){
- if(null==instance){
- instance = new UIAdapter();
- }
- }
- }
- return instance;
- }
- public void init(Context context) {
- if(null==context){
- return;
- }
- WindowManager wm = (WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics displayMetrics = new DisplayMetrics();
- wm.getDefaultDisplay().getMetrics(displayMetrics);
- if(displayMetrics.widthPixels>displayMetrics.heightPixels){//横屏
- screenWidth = displayMetrics.heightPixels;
- screenHeight = displayMetrics.widthPixels;
- }else{
- screenWidth = displayMetrics.widthPixels;
- screenHeight = displayMetrics.heightPixels-getStatusBarHeight(context);
- }
- }
- /**
- * 获取状态栏高度
- * @param context
- * @return
- */
- public static int getStatusBarHeight(Context context) {
- Resources resources = context.getResources();
- int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
- int height = resources.getDimensionPixelSize(resourceId);
- return height;
- }
- public float scaleX(){
- return screenWidth/defaultWidth;
- }
- public float scaleY(){
- return screenHeight/defaultHeight;
- }
- public void scaleView(View v, int w, int h, int l, int t, int r, int b) {
- if(v==null){
- return;
- }
- w = (int) (w*scaleX());
- h = (int) (h*scaleY());
- l = (int) (l*scaleX());
- t = (int) (t*scaleY());
- r = (int) (r*scaleX());
- b = (int) (b*scaleY());
- ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
- if (params != null) {
- params.width = w;
- params.height = h;
- params.setMargins(l, t, r, b);
- }
- }
- }
记得在Application初始化下:
-
- public class MyApp extends Application {
- @Override
- public void onCreate() {
- super.onCreate();
- UIAdapter.getInstance().init(this);
- }
- }
使用:
UIAdapter.getInstance().scaleView(textview,540,200,0,0,0,0);
如果想显示屏幕的1/3的话就是360了宽度,是根据设计师给出来的宽度进行设置
第三种方案: 百分比适配
这是Google 提出来的一个解决适配方案,想要使用必须添加依赖:
implementation 'com.android.support:percent:28.0.0'
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。