Android智能平板应用,界面适配的另一种轻量级方法

简介: Android智能平板应用,界面适配的另一种轻量级方法

Android的界面适配,很常见的需求。


各种设备种类和尺寸那么多,基于一种原型设计好的界面,换到另一种设备上去若不适配全乱套了。好在还是有很多方案的,这减少了不少的开发工作量。最流行的就是头条的方案了,使用也超级简单。然而,如果不想引入,还可以简单的一个工具类实现,原理类似于头条的方案。


这里简单介绍下,使用起来也很简单。


原理就是转换设备的显示像素密度Density。


头条的UI适配的低成本方案AndroidAutoSize也是基于这个原理,只是它封装的更好,稳定性也更好。



就是智能平板UI尺寸虽然不一样,但是长宽比例差不多。比如基于1920*1080的界面尺寸设计的应用,现在新的设备屏幕是1366x768。若不加适配肯定显示不全,若能等比例缩小0.71倍就好了,那么方法是有的。就一个类文件Density.java


package com.newcapec.visitorsystem.utils;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
public class Density {
    /**
     * 设置屏幕像素密度
     * 思路讲解,计算 B601的老固件像素密度1.5 ,新固件像素密度1 600*32/48 = 400
     * 首先我们需要获取当前机型的屏幕密度信息:appDensity,appScaleDensity
     *
     * 我们的设计尺寸会根据默认机型计算出一个固定的以dp为单位的宽度:WIDTH
     *
     * 比如:默认机型的宽高为1080*1920,该设备的屏幕密度为3
     * 那么WIDTH = 1080/3 = 360dp;因此所有适配机型的宽也就等于360dp。
     * 根据 屏幕宽度 / 屏幕密度=WIDTH公式,现在知道屏幕宽度和WIDTH,也就能求出:屏幕密度=屏幕宽度 / WIDHT;
     *
     * 现在屏幕宽度(dp):targetDensity = displayMetrics.widthPixels / WIDTH 求出。
     *
     * 接下来,就需要求出适配机型的scaleDensity
     *
     * appScaleDensity / appDensity = targetScaleDensity / targetDensity ;
     *
     * targetScaleDensity = targetDensity * (appScaleDensity / appDensity) ;
     *
     * densityDpi = density * 160 ;
     *
     * 最后,把获取到的数据,设置到activity的displayMetrics中。
     *
     * 计算出来后,我们需要在绘制view之前先设置好
     *
     * 在onCreate中的setContentView之前添加
     * ———————————————
     * 原文链接:https://blog.csdn.net/weixin_45365889/article/details/102660467
     */
    private final static float WIDTH = 1920;//适配机型的宽为1920dp,屏幕宽/屏幕密度=1920/1=1920
    private static float appDensity;
    private static float appScaleDensity;
    public static void setDensity(Context appcontx, Context contx) {
        //获取当前app的屏幕显示信息
        WindowManager wm = (WindowManager)appcontx.getSystemService(Context.WINDOW_SERVICE);
        int width = wm.getDefaultDisplay().getWidth();
        Log.d("Utils","app width:"+width);
        DisplayMetrics displayMetrics = appcontx.getResources().getDisplayMetrics();
        appDensity = displayMetrics.density;
        appScaleDensity = displayMetrics.scaledDensity;
        Log.d("Utils","appDensity:"+appDensity+",appScaleDensity:"+appScaleDensity);
        //计算等比缩放后的density和scaleDensity
        //WIDTH相对于所有屏幕宽度都是相等的,它是用dp作为单位,所以 屏幕宽度/屏幕密度=WIDTH
        //targetDensity = targetWidht/WIDTH
        float targetDensity = displayMetrics.widthPixels / WIDTH;
        //appScaleDensity/appDensity=targetScaleDensity/targetDensity;
        float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
        int targetDensityDpi = (int) (targetDensity * 160);
        //替换activity的density,appdensity,densityDpi
        DisplayMetrics aDisplayMertics = contx.getResources().getDisplayMetrics();
        Log.d("Utils","presentDensity:"+aDisplayMertics.density+",presentScaleDensity:"+aDisplayMertics.scaledDensity);
        aDisplayMertics.density = targetDensity;
        aDisplayMertics.scaledDensity = targetScaleDensity;
        aDisplayMertics.densityDpi = targetDensityDpi;
        Log.d("Utils","targetDensity:"+targetDensity+",targetScaleDensity:"+targetScaleDensity);
    }
}


注意把里面的WIDTH配置为原设计模型的宽度。


原理介绍



首先我们需要获取当前机型的屏幕密度信息:appDensity,appScaleDensity


我们的设计尺寸会根据默认机型计算出一个固定的以dp为单位的宽度:WIDTH


比如:默认机型的宽高为1080*1920,该设备的屏幕密度为3


那么WIDTH = 1080/3 = 360dp;因此所有适配机型的宽也就等于360dp。


根据 屏幕宽度 / 屏幕密度=WIDTH公式,现在知道屏幕宽度和WIDTH,也就能求出:屏幕密度=屏幕宽度 / WIDHT;


现在屏幕宽度(dp):targetDensity = displayMetrics.widthPixels / WIDTH 求出。


接下来,就需要求出适配机型的scaleDensity


appScaleDensity / appDensity = targetScaleDensity / targetDensity ;


targetScaleDensity = targetDensity * (appScaleDensity / appDensity) ;


densityDpi = density * 160 ;


最后,把获取到的数据,设置到activity的displayMetrics中。


计算出来后,我们需要在绘制view之前先设置好。


使用方法


在BaseActivity的onCreate中调用一下就可以了。


Utils.setDensity(App.getContext(),this);


package com.newcapec.visitorsystem.activity.frontscreen;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.Nullable;
import com.newcapec.visitorsystem.app.App;
import com.newcapec.visitorsystem.threads.ReadCardThread;
import com.newcapec.visitorsystem.utils.Utils;
public class BaseActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Utils.setDensity(App.getContext(),this);
    }
    /*
     * 隐藏系统键盘
     */
    public void hideXtView(){
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        View view = this.getCurrentFocus();
        if (view != null) {
            InputMethodManager inputMethodManager = (InputMethodManager) this.getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }
}


以上只是一个简单的方法,可作为一个学习界面适配原理的例子。但是对于自定义view和listview,RecyclerView是失效的。


这里再介绍下基于头条的UI适配的低成本方案AndroidAutoSize:


AndroidAutoSize对于自定义view,listview,和RecyclerView适配也完全没问题,原理类似。


对于RecyclerView只需在Adapter 的onCreateViewHolder里,调用一下:


AutoSizeCompat.autoConvertDensityOfGlobal(context.getResources());


即可完美适配RecyclerView的UI显示。


AndroidAutoSize:


github地址


https://github.com/JessYanCoding/AndroidAutoSize


gradle引入


implementation 'me.jessyan:autosize:1.1.2'


manifase配置


如果只使用副单位 (pt、in、mm) 就可以直接以像素作为单位填写设计图的尺寸, 不需再把像素转化为 dp


<!-- 如果只使用副单位 (pt、in、mm) 就可以直接以像素作为单位填写设计图的尺寸, 不需再把像素转化为 dp-->
<!-- 用mm副单位开发,这里配置和设计稿一样的尺寸px , 1920 x 1080px -->
<manifest>
    <application>            
        <meta-data
            android:name="design_width_in_dp"
            android:value="1080"/>
        <meta-data
            android:name="design_height_in_dp"
            android:value="1920"/>           
     </application>           
</manifest>


注意上面的meta-data是原始设计尺寸的宽,高。可不用设置成新设备的屏幕尺寸了。


以上基本满足你的基本需求了,若还有问题,可以参见这个贴,汇总了常见问题的解决办法:


https://github.com/JessYanCoding/AndroidAutoSize/issues/13


还有一种屏幕适配方案,原理跟上述的差不多,是AndroidScreenAdaptation。


AndroidScreenAdaptation:


地址:https://github.com/yatoooon/AndroidScreenAdaptation


AndroidScreenAdaptation库特点:


完全不用改变自己的布局编写习惯,你原先是怎么写布局,就怎么写布局.不用去继承适配类,不用在最外层包裹适配布局,不用新建茫茫多的分辨率适配文件夹,不要求强制使用px为单位,可以实时预览布局,全面屏或带虚拟按键手机适配也没问题。


使用:


1.添加依赖


implementation 'me.yatoooon:screenadaptation:1.1.1'


2.初始化工具类


(1)创建自己的application继承Application


public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ScreenAdapterTools.init(this);
    }
//如果应用屏幕固定了某个方向不旋转的话(比如qq和微信),下面可不写.
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        ScreenAdapterTools.getInstance().reset(this);
    }
}


(2)在AndroidManifest.xml文件中声明使用你自己创建的application并且添加meta-data数据,例子上标明了这些数据的代表的意义


<application
        android:name=".App"
        .....
        <meta-data
            android:name="designwidth"
            android:value="1080" />  //设计图的宽,单位是像素,推荐用markman测量,量出来如果是750px那么请尽量去找ui设计师要一份android的设计图.
        <meta-data
            android:name="designdpi"
            android:value="480" />   //设计图对应的标准dpi,根据下面的那张图找到对应的dpi,比如1080就对应480dpi,如果拿到的是其他宽度的设计图,那么选择一个相近的dpi就好了
        <meta-data
            android:name="fontsize"
            android:value="1.0" />   //全局字体的大小倍数,有时候老板会觉得你的所有的字小了或者大了,你总不能一个一个去改吧
        <meta-data
            android:name="unit"
            android:value="px" />   //你的布局里面用的是px这就写px,你的布局里面用的是dp这就写dp,要统一,不要一会儿px一会儿dp,字体也用px或者dp,不要用sp,微信qq用的肯定不是sp.
</application>    



3. 开始使用


(1)在Activity中,找到setcontentview(R.layout.xxxxxx)


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_dp);
        //在setContentView();后面加上下面这句话
        ScreenAdapterTools.getInstance().loadView((ViewGroup) getWindow().getDecorView());
    }
}


注: 自定义view的话,在 ScreenAdapterTools.getInstance().loadView((ViewGroup) view); 外面包裹一层判断如下,不然在使用自定义view编写布局文件时预览xml会有问题!但不影响真机运行效果.


       if (!isInEditMode()) {
            ScreenAdapterTools.getInstance().loadView((ViewGroup) view);
        }    


原理


1. px是分辨率的单位 比如现在主流手机分辨率1080*1920.


2. dp是安卓开发专有的单位 在 不同的手机下 1dp = 不同的 px.


3. sp是字体大小(前面清单文件中要求字体也用dp或者px),sp随系统字体大小变化而变化,但据我观察,像微信qq这些app的字体是不随系统显示字体大小变化的.


### 本库是按照设计图的宽度和对应标准dpi来适配的(宽度增加或减少,高度同比例增加或减少),在不同的分辨率,不同ppi(手机屏幕密度,又称为dpi),不同最小宽度(有的人喜欢去调开发者选项下面的最小宽度,主流手机默认为360dp)的手机下都做到了适配。


引用:


今日头条屏幕适配方案终极版 AndroidAutoSize-玩Android - wanandroid.com


安卓适配AutoSize详解_xxdw1992的博客-CSDN博客_me.jessyan:autosize


Android安卓中最棒的屏幕适配AndroidScreenAdaptation_快乐李同学的博客-CSDN博客_android screen


屏幕适配:修改屏幕像素密度,随便设dp_Android架构师丨小熊的博客-CSDN博客


Andoid屏幕适配终极手段(小编用过最得劲的dp适配)_奋斗的IT青年-CSDN博客_最小宽度多少dp让手机流畅


Android AutoLayout全新的适配方式 堪称适配终结者_Hongyang-CSDN博客_autolayout

相关文章
|
14天前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
37 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
16天前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
121 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
2月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
92 14
|
2月前
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
2月前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
88 0
|
存储 API Android开发
Android适配全面总结(二)----版本适配
版权声明:本文为博主原创文章(部分引用他人博文,已加上引用说明),未经博主允许不得转载。https://www.jianshu.com/p/49fa8ebc0105 转载请标明出处:https://www.
1437 0
|
存储 Android开发 开发者
Android适配全面总结(三)----ROM适配
版权声明:本文为博主原创文章(部分引用他人博文,已加上引用说明),未经博主允许不得转载。https://www.jianshu.com/p/f9c67a4b908e 转载请标明出处:https://www.jianshu.com/p/f9c67a4b908e 本文出自 AWeiLoveAndroid的博客 第一篇文章讲了 Android适配全面总结(一)----屏幕适配 上一篇文章讲了 Android适配全面总结(二)----版本适配 这一篇文章讲一下 ROM适配。
2244 0
|
编解码 API Android开发
|
4天前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
23 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
29天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
79 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    Android历史版本与APK文件结构
  • 3
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 6
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 8
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 9
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 10
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 1
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    13
  • 2
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    28
  • 3
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    34
  • 4
    Android历史版本与APK文件结构
    121
  • 5
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 6
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    23
  • 7
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
    60
  • 8
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    37
  • 9
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    73
  • 10
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    121