【移动应用开发技术】Android屏幕适配的示例分析_第1页
【移动应用开发技术】Android屏幕适配的示例分析_第2页
【移动应用开发技术】Android屏幕适配的示例分析_第3页
【移动应用开发技术】Android屏幕适配的示例分析_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】Android屏幕适配的示例分析

这篇文章主要介绍了Android屏幕适配的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让在下带着大家一起了解一下。测试与思考不得不说今日头条的大神们的想法真的非常独到,成本极其低廉,还特别好用。他们给出的最终方案是这样的:private

static

float

sRoncompatDennsity;

private

static

float

sRoncompatScaledDensity;

private

void

setCustomDensity(@NonNull

Activity

activity,

final

@NonNull

Application

application)

{

//application

final

DisplayMetrics

appDisplayMetrics

=

application.getResources().getDisplayMetrics();

if

(sRoncompatDennsity

==

0)

{

sRoncompatDennsity

=

appDisplayMetrics.density;

sRoncompatScaledDensity

=

appDisplayMetrics.scaledDensity;

application.registerComponentCallbacks(new

ComponentCallbacks()

{

@Override

public

void

onConfigurationChanged(Configuration

newConfig)

{

if

(newConfig

!=

null

&&

newConfig.fontScale

>

0)

{

sRoncompatScaledDensity

=

application.getResources().getDisplayMetrics().scaledDensity;

}

}

@Override

public

void

onLowMemory()

{

}

});

}

//计算宽为360dp

同理可以设置高为640dp的根据实际情况

final

float

targetDensity

=

appDisplayMetrics.widthPixels

/

360;

final

float

targetScaledDensity

=

targetDensity

*

(sRoncompatScaledDensity

/

sRoncompatDennsity);

final

int

targetDensityDpi

=

(int)

(targetDensity

*

160);

appDisplayMetrics.density

=

targetDensity;

appDisplayMetrics.densityDpi

=

targetDensityDpi;

appDisplayMetrics.scaledDensity

=

targetScaledDensity;

//activity

final

DisplayMetrics

activityDisplayMetrics

=

activity.getResources().getDisplayMetrics();

activityDisplayMetrics.density

=

targetDensity;

activityDisplayMetrics.densityDpi

=

targetDensityDpi;

activityDisplayMetrics.scaledDensity

=

targetScaledDensity;

}看到这篇文章之后我赶紧就写了一个demo测试了一下,发现了一点小问题。我们UI给出的设计图尺寸为1334*720,如果我按照宽度作为适配标准的话,按照设计图720px的宽度,屏幕的宽度应为360dp,也就是这样:final

float

targetDensity

=

appDisplayMetrics.widthPixels

/

360;这样做的话宽度适配的比例是没有任何问的,但是我在想,如果需要以高度来做适配(也就是内容刚好纵向填充全屏)的话,是不是改成这样就可以了:final

float

targetDensity

=

appDisplayMetrics.heightPixels

/

667;但是运行之后发现,高度上的差异很大,运行在不同分辨率和尺寸的手机上,页面中的每一部分内容在纵向上的比例不尽相同,没有达到很好的适配的效果。思考了许久过后我发现一个问题:我手边的测试机的宽度是两个720和两个1080,而高度有1280,1440,1780和一个全面屏的2160。Android的开原性导致了Android设备的尺寸的碎片化太严重,而通过查看手机的尺寸参数会发现,如果用这四个手机来测试的话,宽度可以直接整除,而高度不可以(并且我手边的测试机的宽度也可以整除,如果有宽度没法整除的手机呢?)。但是用今日头条给出的方法,做除法后结果会取整,那会不会是由于用纵向计算出来的density取整影响了精度,从而导致了效果不尽人意呢?问题修复发现上述问题之后我就着手去修改,将计算结果取余后在赋值给targetDensity,经过一下午的反复测试与实验,我重新修改了targetDensity的计算方法:float

targetDensity

=

0;

try

{

Double

division

=

Operation.division(appDisplayMetrics.heightPixels,

667);

//由于手机的长宽不尽相同,肯定会有除不尽的情况,有失精度,所以在这里把所得结果做了一个保留两位小数的操作

DecimalFormat

df

=

new

DecimalFormat("0.00");

String

s

=

df.format(division);

targetDensity

=

Float.parseFloat(s);

}

catch

(NumberFormatException

e)

{

e.printStackTrace();

}经测试后发现,这样取两位小数计算过后,高度上的适配结果让人非常满意。可是还有一个问题,我们一般来说做适配都是以手机的宽度为基准,但是一个app里面避免不了偶尔一两个页面是按照高度为基准(就是内容纵向填充全屏的页面)做适配的。但是上述方法只能保证一个方向,那我就让它可以自由的切换适配的基准方向不就好了。最终方案继续修改之后我得到了最终的方案,修改过后这个类中的所有内容如下:private

static

float

appDensity;

private

static

float

appScaledDensity;

private

static

DisplayMetrics

appDisplayMetrics;

//此方法在Application的onCreate方法中调用

Density.setDensity(this);

public

static

void

setDensity(@NonNull

Application

application)

{

//获取application的DisplayMetrics

appDisplayMetrics

=

application.getResources().getDisplayMetrics();

if

(appDensity

==

0)

{

//初始化的时候赋值(只在Application里面初始化的时候会调用一次)

appDensity

=

appDisplayMetrics.density;

appScaledDensity

=

appDisplayMetrics.scaledDensity;

//添加字体变化的监听

application.registerComponentCallbacks(new

ComponentCallbacks()

{

@Override

public

void

onConfigurationChanged(Configuration

newConfig)

{

//字体改变后,将appScaledDensity重新赋值

if

(newConfig

!=

null

&&

newConfig.fontScale

>

0)

{

appScaledDensity

=

application.getResources().getDisplayMetrics().scaledDensity;

}

}

@Override

public

void

onLowMemory()

{

}

});

}

//调用修改density值的方法(默认以宽度作为基准)

setAppOrientation(null,

AppUtils.WIDTH);

}

//此方法用于在某一个Activity里面更改适配的方向

Density.setOrientation(mActivity,

"width/height");

public

static

void

setOrientation(Activity

activity,

String

orientation)

{

setAppOrientation(activity,

orientation);

}

/**

*

targetDensity

*

targetScaledDensity

*

targetDensityDpi

*

这三个参数是统一修改过后的值

*

*

orientation:方向值,传入width或height

*/

private

static

void

setAppOrientation(@Nullable

Activity

activity,

String

orientation)

{

float

targetDensity

=

0;

try

{

Double

division;

//根据带入参数选择不同的适配方向

if

(orientation.equals("height"))

{

//appDisplayMetrics.heightPixels/667

division

=

Operation.division(appDisplayMetrics.heightPixels,

667);

}

else

{

division

=

Operation.division(appDisplayMetrics.widthPixels,

360);

}

//由于手机的长宽不尽相同,肯定会有除不尽的情况,有失精度,所以在这里把所得结果做了一个保留两位小数的操作

DecimalFormat

df

=

new

DecimalFormat("0.00");

String

s

=

df.format(division);

targetDensity

=

Float.parseFloat(s);

}

catch

(NumberFormatException

e)

{

e.printStackTrace();

}

float

targetScaledDensity

=

targetDensity

*

(appScaledDensity

/

appDensity);

int

targetDensityDpi

=

(int)

(160

*

targetDensity);

/**

*

*

***在这里将修改过后的值赋给系统参数

*

*

(因为最开始初始化的时候,activity为null,所以只设置application的值就可以了...

*

所以在这里判断了一下,如果传有activity的话,再设置Activity的值)

*/

if

(activity

!=

null)

{

DisplayMetrics

activityDisplayMetrics

=

activity.getResources().getDisplayMetrics();

activityDisplayMetrics.density

=

targetDensity;

activityDisplayMetrics.scaledDensity

=

targetScaledDensity;

activityDisplayMetrics.densityDpi

=

targetDensityDpi;

}

else

{

appDisplayMetrics.density

=

targetDensity;

appDisplayMetrics.scaledDensity

=

targetScaledDensity;

appDisplayMetrics.densityDpi

=

targetDensityDpi;

}

}这是修改之后的所有内容,不懂的地方可以看一下里面的注释,在里面我是默认的以宽度来作为基准(这是在Activity中设置的方法,存在于此Activity下的fragment,dialog和PopupWindow都会受到此效果的影响,也就是说,在Activity中设置一次之后,Activity下的其他子View都无需再设置一次)。使用方法自己创建一个类,将最终方案里面的代码复制粘贴就可以使用了使用方法:在Application的onCreate()方法中如果只是适配一个方向的话,只设置这一句就可以了(我在utils里面设置了默认按照宽度适配,可以根据自己的需求修改默认的适配方向,见下图)若app中有某一个页面需要纵向适配的话:/**

*

*

由于是个人封装,此方法需要写在onCreate()中的setContentView()方法前面,切换方向的效果才会生效

*/

@Override

public

void

setOrientation()

{

Density.setOrientation(this,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论