android屏幕适配
android设备碎片化严重,因此在实际开发的时候需要做屏幕适配
适配主要是在以下几个方面:
布局适配
常见的布局适配主要是以下几点:
a.避免写死布局尺寸,使用wrap_content或者martch_parent
b.使用权重,比如linearlayout中的weight;
c.使用relative的相对位置摆放,比如layout_centerInParent="true"
d.ConstraintLayout 原理类似于relatvie,相对摆放,但是性能相对于relatvie会好一点
e.android官方的库Percent-support-lib,该库主要是用的是百分比适配
图片资源适配
a. .9图适配,这个是使用了.9图可以在特别区域拉伸不失真的特性来适配
b. 使用多套位图,匹配不同的分辨率,比如在mipmap,mipmap-xhdpi,mipmap-xxhdpi,等文件夹下面放多套分辨率不同的内容相同的图片
用户流程适配
是指同一个业务逻辑,在不同的设备上执行不同的跳转方式,比如在手机上打开一个新的activity,但是在平板上,可以在横屏状态下,右侧增加一个fragment,展示打开的页面。
限定符适配
a.分辨率限定符,使用drawable-dpi,drawable-hdpi等
b.尺寸限定符
c.最小宽度限定符
d.屏幕方向限定符
刘海屏适配
a.android9.0开始 有官方的api进行适配
b.华为,小米,魅族,vivo,oppo各大room厂商有对应的api进行适配
除了以上这些,还有dimens适配,但是都各有缺点,有的需要多套图,有的需要多套资源文件,dimens适配的dimens文件过多,需要针对不同的屏幕分辨率来生成对应的文件,比较繁琐
以上,实际开发中,做的最多的适配为布局适配
本篇文章主要是为了记录一下目前开发中“布局适配”的几种方式
开发中屏幕适配的核心是在于屏幕缩放,不论是哪种屏幕适配,都是以这个缩放为基础
1.自定义像素适配
已知:设计图手机像素(W,H),设计图上控件的像素值(ViewW,ViewH),目标设备分辨率(TargetW,TargetH)
求:目标设备上view的宽高(TargetViewW,TargetViewH)
公式:宽:ViewW / W * TargetW=TargetViewW
高:ViewH / H * TargetH =TargetViewH
原理:根据当前设备的分辨率,计算出设计图上的控件在该设备上的缩放比,然后根据缩放比,来动态的设置view, 最终换算出来的单位为px
该适配方式是通过自定义外部的ViewGroup,比如LinearLayout,RelativeLayout,在onMeasure方法中,遍历子view,设置宽高以及padding,margin
以下是封装了一个工具类,用来获取屏幕宽高以及计算缩放比:
class UiUtils private constructor(private val contxt: Context) {
//设计稿的尺寸
private val STAND_WIDTH = 1080f
private val STAND_HEIGHT = 1920f
private var mDisplayWidth = 0;
private var mDisplayHeight = 0;
companion object {
var instance: UiUtils? = null
fun getInstance(context: Context) {
instance = UiUtils(context)
}
}
init {
if (mDisplayWidth == 0 || mDisplayHeight == 0) {
val metrics = DisplayMetrics()
val windowManager = contxt.getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.defaultDisplay.getRealMetrics(metrics)
if (metrics.widthPixels > metrics.heightPixels) {
//横屏
mDisplayWidth = metrics.heightPixels
mDisplayHeight = metrics.widthPixels - getStatusBarHeight(contxt)
} else {
mDisplayWidth = metrics.widthPixels;
mDisplayHeight = metrics.heightPixels - getStatusBarHeight(contxt)
}
}
}
fun getStatusBarHeight(contex: Context): Int {
val identifier = contex.resources.getIdentifier("status_bar_height", "dimens", "android")
if (identifier > 0) {
return contex.resources.getDimensionPixelSize(identifier)
}
return 0
}
fun getHorizontalScal() = mDisplayWidth / STAND_WIDTH
fun getVeticallScal() = mDisplayHeight / STAND_HEIGHT
}
未完待续