Android友盟一键登录背景全屏显示的问题
1、前言
1.1、友盟一键登录
友盟一键登录是指支持手机号(移动/联通/电信)一键用户验证,无需手动输入账号和短信验证的一种认证SDK;可以简化用户操作,提升注册登录转化率。
1.2、SDK集成
当前最新SDK版本
//友盟一键登录
implementation 'com.umeng.umsdk:uverify:2.5.4'// 必选
implementation 'com.umeng.umsdk:uverify-main:2.1.2'// 必选
implementation 'com.umeng.umsdk:uverify-logger:2.1.2'// 必选
implementation 'com.umeng.umsdk:uverify-crashshield:2.1.2'// 必选
2、设计与实际的差异
UED设计的效果
预期效果.png实际效果
实际效果.pngSDK对于状态栏方面的描述:
1、调用setNavHidden接口隐藏导航栏,使用自定义布局方法(addAuthRegisterXmlConfig )重写导航栏布局一般情况下APP都会设置符合自己UI需求的导航栏
2、如果确定使用默认导航栏即可满足UI需求,则可以简单调用setStatusBarColor 和 setNavColor 设置为相同颜色即可达到全屏效果
3、如果状态栏不需要的情况下,可以直接调用setStatusBarHidden 隐藏掉状态栏即可
它没有特殊背景下沉浸式状态栏设置的描述。
也就是说UED设计使用了特殊的图片背景,在SDK现有提供的接口条件下是无法实现的。
那当前该如何实现呢?当然不能跟UI说不行。
3、图片背景全屏显示实现
1、使用动态XML布局的方式设计整体布局
/**
* 动态添加控件
*
* @param authRegisterXmlConfig 自定义布局,可以设置控件的位置和相关处理逻辑
*/
public void addAuthRegisterXmlConfig(UMAuthRegisterXmlConfig authRegisterXmlConfig)
初始化 UMAuthRegisterXmlConfig 类时需要先调静态内部类Builder()里面的setLayout() 方法,传入layout和 UMAbstractPnsViewDelegate类回调,接着调用Builder获得UMAuthRegisterXmlConfig对象。
2、在UMAbstractPnsViewDelegate类的onViewCreated(View){...}的回调中添加如下代码:
view.addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
if (view.tag == true) return@addOnLayoutChangeListener
var activity: Activity? = null
var curView = v
do {
val p = curView.parent
if (p is ViewGroup) {
curView = p
val ct = curView.context
if (ct is Activity) {
activity = ct
break
}
} else {
break
}
} while (true)
if (activity == null) return@addOnLayoutChangeListener
//设置全屏
curView.postDelayed({
StatusBarUtil.setStatusBarColor(activity, 0)
StatusBarUtil.setFitsSystemWindows(activity, false)
StatusBarUtil.setStatusBarDarkTheme(activity, true)
val paddingtop = StatusBarUtil.getStatusBarHeight(activity)
view.setPadding(0, paddingtop, 0, 0)
//别忘了设置沉浸式背景
view.setBackgroundResource(R.drawable.bg_login)
view.tag = true
}, 200)
}
- 别忘了在Activity onDestroy() 时调用removeAuthRegisterXmlConfig()。否则会有你意想不到的"惊喜"。
4、实现原理
在动态自定义View绘制的过程中拿到Activity对象,对其进行沉浸式状态栏设置,并对布局View设置paddingTop(如果不设置将导致返回键太靠近通知栏,视觉效果拉胯)。
5、几个问题
5.1、为什么需要使用addOnLayoutChangeListener
SDK在onViewCreated(View view)回调时与View绑定的上下文是ApplicationContext不是Activity, 所以不能直接获取使用。所以需要这样”设法“拿到Activity对象。
5.2、为什么使用do{}while()循环
为了确保View绑定的上下文此时是Activity而不是ApplicationContext。也是为了遍历ViewTree以便拿到Activity。
5.3、 为什么curView.postDelayed({})
上文提到,SDK使用非沉浸式状态栏是故意为之。所以这里需要确保这段代码比SDK设置非沉浸式状态栏的代码后执行。可以不这么诡异函数调用吗?延时调用总感觉不稳定---可以。使用Application的registerActivityLifecycleCallbacks(activityLifecycleCallbacks)监听Activity onResume()的时候调用这段代码也可以实现。