IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android屏幕适配很难嘛?其实也就那么回事,从思维图到基础再到深入 -> 正文阅读

[移动开发]Android屏幕适配很难嘛?其实也就那么回事,从思维图到基础再到深入

经测试后发现,这样取两位小数计算过后,高度上的适配结果让人非常满意。可是还有一个问题,我们一般来说做适配都是以手机的宽度为基准,但是一个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, AppUtils.HEIGHT); 
} 

/** 
 * 
 * 如果在一个Activity里面切换了适配方向的话,需要在destroy里面将方向设置为默认的方向, 
 * 因为切换方向修改的是Activity的值,但是application的也会覆盖掉(原因还没有搞清楚...), 
 * 权衡利弊之后就在onDestroy这个生命周期里面重新初始化了一下方向(因为用高度作为适配基准的页面 
 * 少之又少,这样可以最大程度的减少对程序功能性的影响) 
 */ 
@Override 
protected void onDestroy() { 
 super.onDestroy(); 
 Density.setOrientation(this, AppUtils.WIDTH); 
} 

由于在某一个Activity里面切换方向之后,我修改掉的是Activity中的值(activityDensity),但是返回再点击其他页面之后发现其他页面的适配方向也被修改掉了,于是乎权衡利弊之后我就用了这个相对来说影响最小的办法:在需要修改适配方向的Activity中的onDetroy生命周期里面,再手动将方向改成默认。。。(捣鼓了很久实在是想不到更好的办法了,如果各位看官有其他的好办法可以给我留言)。

最后贴出纵向适配的效果图,页面中蓝色背景的TextView高度是固定的150dp(只是我自己写的一个很简单的页面,不要嫌丑。。。):

敲黑板!!!

用此方法写适配,只需要一个dimens文件,一个layout文件就足矣,在xml布局中直接只用dp就可以了(Android P的刘海屏需要单独适配layout,全面屏手机可以隐藏的虚拟按键似乎也需要单独适配。。。)
Onh-1630504187161)]

敲黑板!!!

用此方法写适配,只需要一个dimens文件,一个layout文件就足矣,在xml布局中直接只用dp就可以了(Android P的刘海屏需要单独适配layout,全面屏手机可以隐藏的虚拟按键似乎也需要单独适配。。。)

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-02 11:30:10  更:2021-09-02 11:30:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年2日历 -2025/2/21 1:58:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码