首页 > 其他分享 >Android 屏幕适配

Android 屏幕适配

时间:2023-05-06 12:00:47浏览次数:48  
标签:dimens 适配 makeString replace Android 屏幕 append

一、概念

1.1 屏幕像素密度 PPI、DPI

PPI(Pixels Per Inch)屏幕每英寸容纳多少个像素点,DPI(Dots Per Inch)这个“点”是根据屏幕物理概念产生的一个软件概念,在不同行业有不同理解,印刷行业每英寸打印多少个墨点,鼠标移动一英寸光标移动多少像素点,在Android中被用来表示屏幕每英寸显示多少个像素点,概念上可以当作没有区别。

1.2 密度无关像素 dp

density-independent pixel,是 Android 特有的单位,只与DPI有关,保证了在不同屏幕像素密度的设备上显示相同的效果。以DPI=160为基准1dp=1px,用设备实际DPI值/160=density密度,即1dp=多少px。用屏幕宽或高的px/density=屏幕宽或高最大dp长度。
px = density * dp

density = dpi / 160

1.3 独立比例像素 sp

scale-independent pixel,是 Android 特有的单位,用于设置字体大小。

二、AndroidStudi目录说明

Android会根据手机屏幕分辨率选择对应文件夹中的资源,如果没有对应的文件夹,则从最高分辨率的文件夹依次往低处寻找,找到高分辨率的就压缩后显示,找到低分辨率的就放大显示。

mipmap只用来放桌面应用图标(Manifest中application标签配置的icon项),drawable用来存放图片资源,values用来针对不同分辨力编写对应资源文件。

 

三、屏幕适配

市面上的机型,不同分辨率*不同屏幕尺寸=无限多种DPI组合。当美工给的图以px为单位使用4.1的dimen适配、以dp为单位使用4.2的字节跳动density适配、更推荐的是smallestWidth限定符适配。

dimen宽高适配

穷举市面上所有 Android 手机的屏幕像素尺寸来实现适配,通过比例换算来为不同分辨率的屏幕分别准备一套 dimens 文件,应用在运行时再去引用和当前设备完全匹配的 dimens 文件,以此来实现屏幕适配。

缺点:缺点是容错率低,只有精准匹配分辨率才能适配,否则只能引用默认dimens文件夹,显示效果就会有很大出入。

smallestWidth限定符适配

根据屏幕最短的那个边(不考虑屏幕方向)适配,适配原理和宽高限定符方案一样,也是通过比例换算来为不同尺寸的屏幕分别准备一套 dimens 文件,应用在运行时再去引用和当前设备最匹配的 dimens 文件。

优点:容错率高,没有找到对应dimens文件会向下寻找接近的。在 320 ~ 460 dp 之间每 10 dp 就提供一套 dimens 文件就足够使用了,想要囊括更多设备的话也可以再缩短步长,基本不用担心最终效果会与设计稿偏差太多,且不会影响到三方库。

缺点:需要生成多套 dimens 文件,增大了 apk 体积。

density字节跳动密度适配

基于系统将 dp 转换为 px 的公式 px = dp * density 来实现适配,通过在运行时动态修改 density 值的大小,使得修改后计算出的屏幕宽度就等于设计稿的宽度,从而使得在不同屏幕尺寸下我们都可以直接使用设计稿给出的 dp 值,且无需准备多套 dimens 文件。

优点:可以直接使用设计稿中的 dp 值,无需准备多套 dimens 文件进行映射,因此不会增大 apk 体积,且在三种方案中 UI 还原度最高,其它两种方案都需要精准命中屏幕尺寸后才能达到此方案的还原度。

缺点:由于此方案会影响到应用全局,对于已经迭代了很久的项目来说,中途引入此方案大概率会影响到现有的适配方案;即使是新项目,又需要考虑到此方案对于三方库的影响,不能由于主项目的变动导致三方库自身界面变形。

3.1 dimen宽高适配

 

 

public class DimenUtils {
    private final static String rootPath = "C:/Users/Administrator/Desktop/layoutroot/values-{0}x{1}/"; //注意将Administrator替换为实际用户名
    private final static float dw = 300f;   //屏幕横向分为多少等份
    private final static float dh = 500f;   //屏幕纵向分为多少等份
    private final static String WTemplate = "<dimen name=\"x{0}\">{1}px</dimen>\n"; //xml中横向条目的内容:<dimen name="x1">2.4px</dimen>
    private final static String HTemplate = "<dimen name=\"y{0}\">{1}px</dimen>\n"; //xml中纵向条目的内容:<dimen name="y1">2.56px</dimen>
 
    public static void main(String[] args) {    //AndroidStudio运行失败的话选择 Run 'DimenUtils.main()' with Coverage
        //720P
        makeString(720, 1280);
//        makeString(720, 1520);
//        makeString(720, 1600);
//        makeString(720, 1650);
        //1080P
//        makeString(1080, 1920);
//        makeString(1080, 2160);
//        makeString(1080, 2220);
        makeString(1080, 2340);
//        makeString(1080, 2376);
        makeString(1080, 2400);
//        makeString(1080, 2412);
        //1.5K
//        makeString(1220, 2712);
//        makeString(1240, 2772);
//        makeString(1260, 2800);
        //2K
//        makeString(1440, 2560);
//        makeString(1440, 2960);
//        makeString(1440, 3040);
        makeString(1440, 3200);
    }
 
    public static void makeString(int w, int h) {
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
        sb.append("<resources>");
        float cellw = w / dw;
        for (int i = 1; i < dw; i++) {
            sb.append(WTemplate.replace("{0}", i + "").replace("{1}",
                    change(cellw * i) + ""));
        }
        sb.append(WTemplate.replace("{0}", "300").replace("{1}", w + ""));
        sb.append("</resources>");
 
        StringBuffer sb2 = new StringBuffer();
        sb2.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
        sb2.append("<resources>");
        float cellh = h / dh;
        for (int i = 1; i < dh; i++) {
            sb2.append(HTemplate.replace("{0}", i + "").replace("{1}",
                    change(cellh * i) + ""));
        }
        sb2.append(HTemplate.replace("{0}", "500").replace("{1}", h + ""));
        sb2.append("</resources>");
 
        String path = rootPath.replace("{0}", h + "").replace("{1}", w + "");
        File rootFile = new File(path);
        if (!rootFile.exists()) {
            rootFile.mkdirs();
        }
        File layxFile = new File(path + "lay_x.xml");
        File layyFile = new File(path + "lay_y.xml");
        try {
            PrintWriter pw = new PrintWriter(new FileOutputStream(layxFile));
            pw.print(sb.toString());
            pw.close();
            pw = new PrintWriter(new FileOutputStream(layyFile));
            pw.print(sb2.toString());
            pw.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
 
    }
 
    public static float change(float a) {
        int temp = (int) (a * 100);
        return temp / 100f;
    }
}
//将生成的文件夹直接拖进 AndroidStudio 中的 res 中,使用的时候就 @dimen/ 后跟方向和份数。
<TextView
    android:layout_width="@dimen/x100"
    android:layout_height="@dimen/y250"/>

3.2 smallestWidth 限定符适配

GitHub - ladingwu/dimens_sw: Android UI适配方案

3.3 density 字节跳动密度适配

一种极低成本的Android屏幕适配方式 (qq.com)

 

(332条消息) Android - 屏幕适配_android dimen适配_Jomurphys的博客-CSDN博客

标签:dimens,适配,makeString,replace,Android,屏幕,append
From: https://www.cnblogs.com/wanglongjiang/p/17376836.html

相关文章

  • linux 通过命令行(包括ssh)关闭屏幕
    题外话:不得不说现在百度的搜索真的烂,除了广告,有用的信息一点也搜不到,bing倒是广告少,照样也搜不到有用信息,谷歌虽然作恶不少,某些技术还是可以的,但是国内不通过特殊方法又使用不了,解决方法:1.找谷歌的镜像站,但是不好找,就算找到了,可能过几天就失效了;2.找一些小众的搜索......
  • Android开发--WebView, WebChromeClient和WebViewClient
     WebView是AndroidAPP用来处理html页面的一个组件webview是android中的浏览器控件,在一些手机应用中常会用到b/s模式去开发应用,这时webview的强大功能就会显示出来。webview的几点设置   权限设置:.AndroidManifest.xml中必须使用许可"android.permission.INTERNET",否则会......
  • Android开发--事件绑定及startActivity、startActivityForResult区别
      一、绑定事件的方法:1、方法一:UI组件事件属性调用main.xml:<Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="forWard"an......
  • Android开发--架构详解
    Android体系架构详解:http://www.ibm.com/developerworks/cn/opensource/os-cn-android-build/#ibm-pcon    src文件夹是项目的所有包及源文件(.java)(与一般的Java项目一样)分析HelloAndroid项目的主程序文件HelloAndroid.java,如代码清单3-8所示。代码清单3-8HelloAndroid.java......
  • deepspeech_android_devices_support
    AndroiddevicessupportWehavesupportforAndroidrelyingonTensorFlowLite,withJavaandJNIbindinds.Formoredetailsonhowtoexperimentwiththose,pleaserefertothesectionbelow.PleaserefertoTensorFlowdocumentationonhowtosetupthee......
  • Android 数据存储
    概述文件存储特点:openFileInput()和openFileOutput()读取设备上的文件。SharedPreferences特点:以XML格式将数据存储到设备。SQLite数据库特点:运算速度快,占用资源少,还支持基本SQL语法。ContentProvider特点:应用程序之间的数据交换,可以将自己的数据共享给其他应用......
  • Android 程序活动单元Activity
    点击按钮页面跳转在xxxActivity类,创建按钮对象对按钮对象创建匿名内部类监听器记得选View.OnClickListener()在内部类建立Intent跳转对象:newIntent(原界面,目标界面)Intentintent=newIntent(LoginActivity.this,MainActivity.class);使用startActivity启动跳转......
  • android压力测试命令monkey详解
    一、Monkey是什么?Monkey就是SDK中附带的一个工具。二、Monkey测试的目的?:该工具用于进行压力测试。然后开发人员结合monkey打印的日志和系统打印的日志,结局测试中出现的问题。三、Monkey测试的特点?Monkey测试,所有的事件都是随机产生的,不带任何人的主观性。四、Monkey命令......
  • Android studio Failed to start [powershell.exe]
    无法打开本地终端解决办法:1、在file→settings→Tools→Terminal→Shellpath中把值设置为电脑系统 powershell.exe文件的全路径(如下图)  ......
  • 适配器模式
    适配器模式2个接口,普通播放器,高级播放器普通播放器MediaPlayerpublicinterfaceMediaPlayer{ voidplay(StringaudioType,StringfileName);}高级播放器AdvancedMediaPlayerpublicinterfaceAdvancedMediaPlayer{ voidplayVlc(StringfileName); voidplayMp4......