Android pad适配札记

题引:随着国产平板的崛起,越来越多的应用开始适配平板。Android系统的开源注定了它产品的多样性,iOS平板只有固定几个尺寸适配较为简单。但Android平板不一样,尺寸随心所欲。很多手机竖屏的应用在平板上有更多的展示方式,适配变得更加艰难!(本文主要写些关于平板适配的心得,以及与设计对线后的感悟!)

细细想想适配的点有哪些:

  1. dp 与 px
  2. 资源的读取

关于 dp 与 px 的处理

Android尺寸五花八门,计算出来的宽高dp也有很多种

    //  计算函数
    private fun getAndroidScreenProperty() {
        val wm = this.getSystemService(WINDOW_SERVICE) as WindowManager
        val dm = DisplayMetrics()
        wm.defaultDisplay.getMetrics(dm)
        val width = dm.widthPixels // 屏幕宽度(像素)
        val height = dm.heightPixels // 屏幕高度(像素)
        val density = dm.density // 屏幕密度(0.75 / 1.0 / 1.5)
        val densityDpi = dm.densityDpi // 屏幕密度dpi(120 / 160 / 240)
        // 屏幕宽度算法:屏幕宽度(像素)/屏幕密度
        val screenWidth = (width / density).toInt() // 屏幕宽度(dp)
        val screenHeight = (height / density).toInt() // 屏幕高度(dp)
        Log.d("linmutang", "屏幕宽度(像素):$width")
        Log.d("linmutang", "屏幕高度(像素):$height")
        Log.d("linmutang", "屏幕密度(0.75 / 1.0 / 1.5):$density")
        Log.d("linmutang", "屏幕密度dpi(120 / 160 / 240):$densityDpi")
        Log.d("linmutang", "屏幕宽度(dp):$screenWidth")
        Log.d("linmutang", "屏幕高度(dp):$screenHeight")
    }

常见的尺寸 1080px * 1920px 可换算为 360dp * 680dp ,这个也是我们一般适配的标准尺寸
在这里插入图片描述

可那些非常规的呢

//  华为Mate10/ALP-TL00
com.miss.soullink D/linmutang: 屏幕宽度(像素):1440
com.miss.soullink D/linmutang: 屏幕高度(像素):2448
com.miss.soullink D/linmutang: 屏幕密度(0.75 / 1.0 / 1.5):3.375
com.miss.soullink D/linmutang: 屏幕密度dpi(120 / 160 / 240):540
com.miss.soullink D/linmutang: 屏幕宽度(dp):426
com.miss.soullink D/linmutang: 屏幕高度(dp):725

//  华为 P40 Pro
com.miss.soullink D/linmutang: 屏幕宽度(像素):1200
com.miss.soullink D/linmutang: 屏幕高度(像素):2499
com.miss.soullink D/linmutang: 屏幕密度(0.75 / 1.0 / 1.5):3.33125
com.miss.soullink D/linmutang: 屏幕密度dpi(120 / 160 / 240):533
com.miss.soullink D/linmutang: 屏幕宽度(dp):360
com.miss.soullink D/linmutang: 屏幕高度(dp):750

如果一个控件的宽度是180dp,在P40机子上就是屏幕宽度的一半,在Mate10则有偏差,那该怎么解决?

方案一 使用最小宽度适配符

在这里插入图片描述

原理比较简单,根据适配符规则(sw 最小宽度)列举市面上通用的尺寸,以360dp为基准。如果是426dp的,则化为360等份,每一等份占 (426/360)= 1.2 dp ,如此一来布局文件的 10dp 可以用 dp_10 来代替,不论任何尺寸下,dp_10 的长度都是宽度的 10/360 。

适配的规则是向下取值,比如一款手机的最小宽度是550dp,咱们生成的目录里有values-sw540dp、values-sw592dp。资源读取时是向下取值,会取values-sw540dp中的值

px 与 dp 同理

参考网站:
https://www.jianshu.com/p/1302ad5a4b04
https://developer.android.com/guide/topics/resources/providing-resources

方案二 头条的适配方案,修改density

px值 = dp值 * metrics.density ,这里的 density 是指的手机的屏幕密度,由系统提供,不同的手 机的 density 可能不同;所以我们不能直接使用系统的 density ,需要篡改 density 来达到适配的目的。

// 系统的Density
private static float sNoncompatDensity;
// 系统的ScaledDensity
private static float sNoncompatScaleDensity;

private static void setCustomDensity(Activity activity, final Application application){
    final DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();

    if(sNoncompatDensity == 0){
        // 系统的Density
        sNoncompatDensity = appDisplayMetrics.density;
        // 系统的ScaledDensity
        sNoncompatScaleDensity = appDisplayMetrics.scaledDensity;
        // 监听在系统设置中切换字体
        application.registerComponentCallbacks(new ComponentCallbacks() {
            @Override
            public void onConfigurationChanged(@NonNull Configuration newConfig) {
                if(newConfig != null && newConfig.fontScale > 0){
                    sNoncompatScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
                }
            }

            @Override
            public void onLowMemory() {

            }
        });
    }
    // 此处以360dp的设计图作为例子
    final float targetDensity = appDisplayMetrics.widthPixels / 360;
    final float targetScaledDensity = targetDensity * (sNoncompatScaleDensity/sNoncompatDensity);
    final int targetDensityDpi = (int)(160 * targetDensity);

    appDisplayMetrics.density = targetDensity;
    appDisplayMetrics.scaledDensity = targetScaledDensity;
    appDisplayMetrics.densityDpi = targetDensityDpi;

    final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
    activityDisplayMetrics.density = targetDensity;
    activityDisplayMetrics.scaledDensity = targetScaledDensity;
    activityDisplayMetrics.densityDpi = targetDensityDpi;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //	此处调用---一般都是在BaseActivity中
    setCustomDensity(this,this.getApplication());
    setContentView(R.layout.activity_main);
}

资源的读取

layout的读取比较简单,完全可以用适配符区分,通过 layout-land 区分横竖屏,也可以通过 layout-large 屏幕尺寸区分。

drawable资源读取则比较麻烦,不过也有窍门。目前的手机基本都是符合xxhdpi(三倍图,即 dp * 3 = px ),图片资源基本放这里就可以。之于平板的则可以放在xhdpi(二倍图,即 dp * 2 = px )中

在这里插入图片描述

平板适配经验

产品的想法:微调

平板的尺寸给了产品更多的想象空间,有些界面在手机、平板都是横屏,手机的展示较为狭窄,所以产品老师会做一些调整。这些调整不大,可能是字号的微调,可能是间距的微调。

如果只是这种级别的微调写两套布局就显得很不值得,维护成本较高。而且吧,sw哪一套还用不上。对于这一类的适配可以借用sw的思想创建 values-large 和 values-xlarge 目录。定义一个变量名,在手机上可以使用sw那套,平板上则从 values-xlarge 目录中取值,做定制化适配即可。
在这里插入图片描述

这样的好处是只需要写一套layout,当然调试也比较简单,AS提供了各种尺寸的机型预览,没有的也可以通过 Add Device Definition 创建相应的机型预览
在这里插入图片描述

在这里插入图片描述

产品的想法:手机竖屏、pad横屏

在这里插入图片描述

设计的想法是这样的,手机的高度与平板的宽度是一样,平板横屏可以采用手机横向拉伸的结果。。。如果啥也不改动只是单纯的使纵向布局旋转为横向布局,结果好像大雄拉伸成了胖虎

此处有两个思路:

  1. 通过变量名用资源适配符适配,用 -xlarge 区别是否是平板。好处依旧是一套布局,维护成本较低,麻烦的是每个尺寸、字号都要定义,需要一直切换文件夹调整
  2. 直接使用两套布局,通过 layout-land 或 layout-large 区分

最后,强烈推荐好好看看Android的开发文档,能解决很多问题
应用资源概览

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Pad版本开发是为了平板电脑的操作系统和硬件特性进行应用程序的开发。相比于手机版本的开发,Android Pad版本开发需要更多地考虑到平板电脑的大屏幕和高分辨率,以及更强大的处理能力。 在Android Pad版本开发中,需要优化布局和界面设计,以充分利用大屏幕的空间和显示效果。通过合理的布局设计,可以提供更好的用户体验,使用户能够更方便地操作和浏览应用程序的内容。 此外,Android Pad版本开发还需要考虑平板电脑的硬件特性,如多点触控和加速度传感器等。利用这些硬件特性,可以为用户提供更多的交互方式,增强应用程序的功能性和娱乐性。 Android Pad版本开发还需要考虑平板电脑的性能和电池寿命。由于平板电脑一般具有更强大的处理能力,可以运行更复杂的应用程序,但同时也需要更多的电池资源。因此,在开发过程中需要优化代码和功能,降低功耗,以延长电池使用时间。 另外,对于应用程序的性也需要考虑。不同厂商和型号的平板电脑可能存在屏幕分辨率、硬件规格、操作系统版本等方面的差异,需要进行相应的和测试,确保应用程序在不同的平板电脑上都能够正常运行。 综上所述,Android Pad版本开发需要对平板电脑的特性和限制有深入的了解,并进行相应的优化和,以提供更好的用户体验和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值