1. 横竖屏适配
横竖屏适配存在问题
布局问题
- 布局文件适配:通过在res下创建布局文件夹,区分横竖屏加载不同的布局文件,布局文件名需保持一致
layout-land:横屏layoutlayout-port:竖屏layout
- 代码适配:可使用
resources.configuration.orientation获取横竖屏状态,默认情况下横竖屏切换会重走Activity#onCreate(),可在此判断加载不同的layout文件
- Configuration.ORIENTATION_LANDSCAPE:横屏
- Configuration.ORIENTATION_PORTRAIT:竖屏
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
when (resources.configuration.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> {
// 横屏
setContentView(R.layout.layout_landscape)
}
else -> {
// 默认加载竖屏
setContentView(R.layout.layout_portrait)
}
}
}
重新加载问题
- 在布局问题的第2点中有提到,默认情况下横竖屏切换会重走
Activity#onCreate(),可在其中加载不同的布局文件,若需保存切换前的页面状态数据,还需做数据保存恢复处理
/**
* 恢复数据,回调此方法savedInstanceState一定不为空
*
* 调用时机:
* 1. 横竖屏切换时
* 2. 异常被杀时(例:内存不足时)
*/
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
val state = savedInstanceState.getString("")
...
}
/**
* 可做保存数据操作,用于恢复之前状态
*
* 调用时机:
* 1. 按下Home键时
* 2. 横竖屏切换时
*
* 当前主流系统版本此方法回调时机在onStop()之后
*/
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("", "")
...
}
- 在
AndroidManifest.xml中加入android:configChanges配置,可改变其生命周期回调
android:configChanges:若未指定,系统中发生这些配置的更改,Activity都会重新启动,配置后只会回调Activity#onConfigurationChanged
例:android:configChanges="orientation|keyboardHidden"
- android:configChanges="orientation":横竖屏旋转
- android:configChanges="keyboardHidden":键盘显示与隐藏
- android:configChanges="keyboard":键盘变更(例:12键变全键盘)
- android:configChanges="fontScale":字体变更
- android:configChanges="locale":语言变更
- android:configChanges="touchscreen|navigation":触摸屏或导航方式变更
可在Activity#onConfigurationChanged中监测横竖屏状态或键盘状态做额外逻辑处理
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
when (newConfig.orientation) {
Configuration.ORIENTATION_PORTRAIT -> {
// 竖屏
}
Configuration.ORIENTATION_LANDSCAPE -> {
// 横屏
}
}
when (newConfig.hardKeyboardHidden) {
Configuration.HARDKEYBOARDHIDDEN_NO -> {
// 实体键盘弹出
}
Configuration.HARDKEYBOARDHIDDEN_YES-> {
// 实体键盘隐藏
}
}
}
android:configChanges补充
未设置时,横竖屏切换会重走各生命周期,切横屏执行一次,切竖屏执行两次 仅设置值为orientation时,切屏还是会重走生命周期,切横、竖屏只会执行一次 设置值为orientation|keyboardHidden时,切屏不会重走各生命周期,只会执行onConfigurationChanged()
- 在
AndroidManifest.xml中加入android:screenOrientation配置,可强制屏幕状态
- android:screenOrientation="portrait":强制竖屏
- android:screenOrientation="landscape":强制横屏
- android:screenOrientation="unspecified":默认值,系统判断,自动切换
- android:screenOrientation="user":当前用户设置的横竖屏状态
- android:screenOrientation="behind":与前一个显示的Activity方向一致
- android:screenOrientation="sensor":使用传感器的方向
- android:screenOrientation="nosensor":忽略传感器方向(例忽略重力感)
代码设置强制屏幕状态
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 强制横屏
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
setContentView(view)
...
}
2. 屏幕尺寸适配
安卓设备种类繁多,小到智能手表,大到智能手机、平板电脑,甚至电视,屏幕尺寸千差万别,要做到适配所有机型,实属不易!!!
此处只介绍几款手机的适配方案,其他类似
layout适配
手机屏幕大小不一,480320、640360、800*480...,要做到各屏幕其实很简单,只需在res下创建不同layout文件夹即可,系统会加载合适的layout
layout-640*360:640*360layout-800*480:800*480layout-land-800*480:横屏布局800*480layout-small:480dp*320dplayout-large:640dp*480dplayout-xlarge:960dp*720dp
drawable适配
系统会根据分辨率加载合适的图片
- drawable:默认
- drawable-ldpi:低密度图片(0dpi~120dpi)
- drawable-mdpi:中等密度图片(120dpi~160dpi)
- drawable-hdpi:高密度图片(160dpi~240dpi)
- drawable-xhdpi:超高密度图片(240dpi~320dpi)
- drawable-xxhdpi:超超高密度图片(320dpi~480dpi)
- drawable-xxxhdpi:超超超高密度图片(480dpi~640dpi)
- drawable-nohdpi:无缩放
dimen适配
- values-sw320dp/dimens.xml(320dp 宽设备)
<dimen name="button_width">120dp</dimen>
<dimen name="margin_common">8dp</dimen>
<dimen name="text_size">14sp</dimen>
- values-sw480dp/dimens.xml(480dp 宽设备)
<dimen name="button_width">160dp</dimen>
<dimen name="margin_common">12dp</dimen>
<dimen name="text_size">16sp</dimen>