Android屏幕适配实例教程「今日头条,AutoSize」

Android屏幕适配实例教程

即使只是练习项目,仍然要使用屏幕适配,这样我们就可以跟着设计图上的单位参数敲,效率会快很多

项目的示范代码使用kt语言,但没有用到什么高级特性,完全不懂的参考这个链接,文章参考代码已经上传到Github,本篇相关的设计图链接戳这里

这里提供一个App的UI设计图小白日记,仅供参考

前期与UI之间的沟通

1)确定设计图基准

=可以简单理解为以某个尺寸为基准,然后通过改变对应的比例的方式去设置真实的单位数值,这就意味了我们在开发之前要和UI设计师沟通好基准设计图的宽高尺寸,单位是px或dp有,通常Android是以360*640dp为基准

2)标注方式

推荐使用蓝湖(https://lanhuapp.com/?home),切图统一使用上传蓝湖的形式,避免微信,U盘传输带来的版本混乱问题,拿到UI给的分享链接后,就可以查看需要的数据了

而且它自带转换功能,所以如果UI设计是以某一px尺寸为单位设计,它也可以帮你转换成相应的dp数值

今日头条屏幕适配方案

1)配置

基于头条屏幕方案的AndroidAutoSize,使用方式,先在module下的build.gradle下添加依赖

 implementation 'me.jessyan:autosize:1.1.2'

然后在module的AndroidManifest权限菜单下添加基本设计图的尺寸,这里我们是使用360*630dp作为基本尺寸单位,这样配置工作就完成了


                
        
                   
                

一般来说,只要我们按照基准设计图的尺寸写AutoSize就可以为我们进行适配了,当在一些特殊情况下我们还要进行一些配置。

头条的适配方案是选择高度或宽度两者之一为基准进行适配(姑且不管原理),在该库的AutoSizeConfig类的源码中我们可以看到isBaseOnWidth默认就是true,也就是说改库默认就是以宽度进行适配的

isBaseOnWidth.png

2)宽度适配,高度适配,取消适配

那什么样的页面是用高度适配比较合适,什么样的页面是用宽度适配比较合适呢

比如我们使用ScrollView包裹着线性布局,这种页面就使用宽度适配比较合适,因为它宽度是确定的了,高度是不确定的,所以就使用宽度适配


    

        

            
        
    

框架默认是使用宽度适配的,因此我们不需要对Activity进行操作,而如果是HorizontalScrollView,宽度是不确定的,高度是确定的,就适合以高度为基准进行适配

在HeightActivity中实现CustomAdapt接口,实现isBaseOnWidth方法,返回false表示不要以宽度为基本适配,然后在getSizeInDp方法中填写基准设计图高度的尺寸

/**
 * Created by 舍长
 * describe:
 */
class HeightActivity : AppCompatActivity() , CustomAdapt {

    //取消以宽度为基准进行适配
    override fun isBaseOnWidth(): Boolean {
        return false
    }

    //返回高度的单位尺寸
    override fun getSizeInDp(): Float {
        return 640f
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_height)
    }
}

如果我们应用绝大多页面都是适合用高度来进行适配的,我们不希望创建的Activty默认使用宽度进行适配,那么我们就可以在Application的onCreate方法中进行全局的适配

/**
 * Created by 舍长 on 2019/5/9
 * describe:
 */
class App: Application() {
    override fun onCreate() {
        super.onCreate()
        //默认使用宽度适配
        AutoSizeConfig.getInstance().isBaseOnWidth = false
    }
}

最后在权限菜单中引用这个Application就可以了,这个时候创建出来的Activity就默认是使用高度适配了,如果我们想在某个类中再次使用宽度适配,就再次继承CustomAdapt接口实现上面的两个方法就可以了

    override fun isBaseOnWidth() = true
    override fun getSizeInDp() = 360F//基本宽度的尺寸

我们如果想取消屏幕适配,就让Activity实现CancelAdapt接口。

3)沉浸式页面的配置

我们经常会有需要使用沉浸式页面的需求,这里的沉浸式不是指状态栏换一个颜色,而是页面没有状态栏,也就是全屏页面,如闪屏页,视频播放,游戏等等

闪屏页面.png

我们可以通过设置主题来让Activity全屏化






然后让Activity继承于该主题就可以了,但是当我们把页面写好后,却发现页面的内容好像比实际的距离总要往上那么一点?这是怎么回事?

我们看看设计图,并仔细观察紫色圆点的位置

ui.png

然而我们按照UI设计图的尺寸在dpi为440的机器上添加出来的圆点效果却是这样的,明显比我们预期的往左和往上了一些(如果你运行出来觉得效果没错,其实是碰巧,换多几个dpi的机型就不行了)

mobile.png

这是因为AutoSize默认的适配范围是不包括状态栏那块位置,当你使用全屏后他不知道,所以我们可以在Activity中这样配置一下,让他将状态栏的位置也算上去

/**
 * Created by 舍长 
 * describe:当使用全屏主题时,我们要使用设备的真实尺寸
 */
class Full2Activity : AppCompatActivity(), CustomAdapt {
    override fun isBaseOnWidth(): Boolean {
        return false
    }

    override fun getSizeInDp(): Float {
        return 640f
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        AutoSizeConfig.getInstance().isUseDeviceSize = true//使用设备的完整尺寸
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_full2)
    }
}

但是如果我们进入源码中看会发现他默认好像是就是true啊!其实是他在InitProvider类中有重新赋值为false了

    @Override
    public boolean onCreate() {
        AutoSizeConfig.getInstance()
                .setLog(true)
                .init((Application) getContext().getApplicationContext())
                .setUseDeviceSize(false);
        return true;
    }

这里使用竖屏适配的页面是为了方便测试,因为如果是普通的页面会出现图片宽高比不同,图片要经过裁剪才能全屏显示,这就无法直观的看到效果

AutoSize开源库的单位数值转换

在自定义控件总,因为绘图类的单位总是px,所以我们经常使用到单位数值转换,也就是dp,px,sp之间的转换,

我们使用该开源库后,它里面就有很多单位转换工具类了,我们可以进行充分的利用

我们先来看看用法吧


    /**
     * sp转px
     */
    fun sp2px(context:Context,value:Float){
        AutoSizeUtils.sp2px(context, value)
    }

但是这样用好像挺麻烦的,在kotlin中,一个方法在整个模块都是可以用到的,所以我们在Application中封装个全局的context

/**
 * Created by 舍长 on 2019/4/9
 * describe:
 */
class App : BaseApplication() {
    companion object {
        var _context: Application? = null
        fun getContext(): Context {
            return _context!!
        }

    }

    override fun onCreate() {
        super.onCreate()
        _context = this
    }
}

然后新建一个Screen的kt文件来封装方法,具体实现后就是这样的

/**
 * Created by 舍长 on 2019/4/25
 * describe:屏幕单位获取,转换扩展扩展kt文件
 */
//dp转px
fun dp2px(value: Float) {
    AutoSizeUtils.dp2px(App.getContext(), value)
}

//sp转px
fun sp2px(value: Float) {
    AutoSizeUtils.sp2px(App.getContext(), value)
}

//获取屏幕宽度
fun screenWidth(): Int {
    val screenSize = ScreenUtils.getScreenSize(App.getContext())
    return screenSize[0]//宽度
}

//获取屏幕高度
fun screenHeight(): Int {
    val screenSize = ScreenUtils.getScreenSize(App.getContext())
    return screenSize[1]//高度
}

后面我们需要用到时就直接在类里调相应的方法名字就可以了

dp2px(20f) //dp转px
sp2px(20f) //sp转px

图片的适配

如果UI已经将图切好并上传到蓝湖,我们只需要拿到xxhdpi文件夹下的图片,并放置到自己的xxhdpi文件夹就可以了,mipmap-xxhdpi是默认就有的,我们也可以自己创建一个drawable-xxhdpi

xxhdpi库.png
微信截图_20190515133328.png

就可以适配所有手机App了,这样我们就不需要再将每个图片都写大小,只要wrap_content就可以了,Android小太高了会自动帮我们完成适配的过程

      

到这里,我们基本上就可以完成适配的工作了,本篇文章只是为了后面的实战文章做铺垫,虽然没有涉及原理,但是在实现上还是没有任何问题的

当然除了今日头条这种适配方案外,也有使用多套px文件来进行适配的项目,可以去鸿洋大佬的博客看看

你可能感兴趣的:(Android屏幕适配实例教程「今日头条,AutoSize」)