下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 幼师配班工作总结
- 来料检验员工作总结
- 收款委托书(3篇)
- 福建省莆田市2024−2025学年高二上学期第一次月考数学试卷含答案
- 读书活动阅读心得体会
- 吉林省长春市(2024年-2025年小学五年级语文)人教版开学考试((上下)学期)试卷及答案
- 福建省泉州市(2024年-2025年小学五年级语文)人教版课后作业(下学期)试卷及答案
- 茶文化与茶艺鉴赏 教案全套 杨环焕 项目1-6 寻茶源 中国茶文化- 品茶韵 常见茶叶的冲泡与鉴赏
- 护理工作年终总结汇报
- 上海市县(2024年-2025年小学五年级语文)统编版质量测试((上下)学期)试卷及答案
- 新时代智慧物流行业人才培养与团队建设方案
- 2024年公司市场化选聘经理层考核管理办法
- 太阳能光伏电站施工安全标准化建设考核试卷
- 防炫(AG工艺)玻璃项目可行性研究报告模板-备案拿地
- 煤炭洗选工艺数字化与智能化
- 2024年【汽车驾驶员(技师)】证模拟考试及答案
- 临床医学:肿瘤标志物
- 瑜伽脊柱扭转课程设计
- 风电项目风机吊装专项施工方案
- 2024版供应链代理采购合同协议书范本
- 室外燃气管道安装施工方案
评论
0/150
提交评论