android屏幕朝向,Android10 屏幕方向适配

问题

假如项目突然有一个支持pad的需求,需要将所有的页面都支持横屏,该怎么做?

常见方案:

将manifest的中活动的screenOrientation属性都固定为unspecified,问题就是手动修改十分麻烦,且项目本身是增量编译的情况下,必须使用耗时的全量编译才行;

使用BaseActivity或者ActivityLifecycleCallbacks中动态去设置(kotlin):

requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED

问题在于这种方式在Android10上有问题,横屏跳转到下一个活动,手机会先竖屏展示,然后再自动切成横屏,也就是“跳一下”。

问题解决

目标一:自动化修改manifest文件,使其支持增量编译

思路:在Gradle构建APK的过程中,在总的manifest文件生成(每个Module的manifest文件自动合并后)之后,将所有的screenOrientation都改动成unspecified,这样不管在哪种编译模式下都能将所有页面都改动到:

//在app下的build.gradle文件末尾中添加

//此处是kts脚本,换成groovy脚本照着抄就行,大同小异

//将所有的竖屏修改为unspecified,为了测试,临时把代码放在这里

//项目构建之后

project.afterEvaluate {

//获取输入,包含了资源输入和manifest输入(输入-transform-输出)

//其实也可以自己对 process[XXX]Manifest 相关的几个task直接操作

android.applicationVariants.forEach { variant->

variant.outputs.forEach { output ->

val manifestTask = output.processManifestProvider.orNull

if (manifestTask != null) {

doLastReplaceManifest(manifestTask)

} else {

val taskName = output.processManifestProvider.name

project.tasks.whenTaskAdded(object : Action {

override fun execute(t: Task) {

if (t.name == taskName) {

doLastReplaceManifest(output.processManifestProvider.get())

}

}

})

}

}

}

}

fun doLastReplaceManifest(task: com.android.build.gradle.tasks.ManifestProcessorTask) {

task.doLast {

val startTime = System.currentTimeMillis()

val manifestPath = "${task.manifestOutputDirectory.get().asFile.absolutePath}/AndroidManifest.xml"

val file = file(manifestPath)

if (!file.exists()) {

println("not find manifest file, path=${file.absolutePath}")

return@doLast

}

val str = file.readText()

file.setWritable(true)

file.writeText(str.replace(

"screenOrientation=\"portrait\"",

"screenOrientation=\"unspecified\""

))

println("replace portrait to unspecified, spent ${System.currentTimeMillis() - startTime}ms")

}

}

其实方案一有一个问题就是,当需要动态改变屏幕方向的时候就还是会“跳一下”。

例如在上面的基础上再加上下面的动态代码(固定为横屏)

requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE

目标二:解决安卓10动态修改屏幕方向“跳一下”问题

在探索时发现,对于一个活动,manifest中它的screenOrientation只是locked的时候,动态去修改屏幕方向,它就不会再“跳一下”。

举个简单例子:

//manifest.xml

android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"

android:screenOrientation="locked">

//Activity.kt

override fun onCreate(savedInstanceState: Bundle?) {

requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE

super.onCreate(savedInstanceState)

}

至于自动化的过程,请参照方案一。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值