大家好,又见面了,我是你们的朋友全栈君。
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作为基本尺寸单位,这样配置工作就完成了
android:name=”design_width_in_dp”
android:value=”360″/>
android:name=”design_height_in_dp”
android:value=”640″/>
一般来说,只要我们按照基准设计图的尺寸写AutoSize就可以为我们进行适配了,当在一些特殊情况下我们还要进行一些配置。
头条的适配方案是选择高度或宽度两者之一为基准进行适配(姑且不管原理),在该库的AutoSizeConfig类的源码中我们可以看到isBaseOnWidth默认就是true,也就是说改库默认就是以宽度进行适配的
isBaseOnWidth.png
2)宽度适配,高度适配,取消适配
那什么样的页面是用高度适配比较合适,什么样的页面是用宽度适配比较合适呢
比如我们使用ScrollView包裹着线性布局,这种页面就使用宽度适配比较合适,因为它宽度是确定的了,高度是不确定的,所以就使用宽度适配
android:layout_width=”match_parent”
android:layout_height=”match_parent”>
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:orientation=”vertical”>
框架默认是使用宽度适配的,因此我们不需要对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全屏化
@color/colorPrimary
@color/colorPrimaryDark
@color/colorAccent
true
然后让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小太高了会自动帮我们完成适配的过程
android:layout_marginTop=”313dp”
android:layout_marginLeft=”470dp”
android:src=”@drawable/circle”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”/>
到这里,我们基本上就可以完成适配的工作了,本篇文章只是为了后面的实战文章做铺垫,虽然没有涉及原理,但是在实现上还是没有任何问题的
当然除了今日头条这种适配方案外,也有使用多套px文件来进行适配的项目,可以去鸿洋大佬的博客看看
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/135278.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...