第二篇文讲到,SplashActivity判断用户没有登录过后就是隐式启动OpenSourceLoginActivity,如果判断系统为安卓5.0+。则进行共享元素动画,可以看到LoginActivity中的actionStartWithTransition代码
if (AndroidVersion.hasLollipop()) {
intent.putExtra(START_WITH_TRANSITION, true)
val options = ActivityOptions.makeSceneTransitionAnimation(activity, logo,
activity.getString(R.string.transition_logo_splash))
activity.startActivity(intent, options.toBundle())
} else {
activity.startActivity(intent)
activity.finish()
}
有关共享元素动画,我搜了一下找到一篇文章可以很清楚的说明白activity跳转时共享元素的简单使用
跳转到OpenSourceLoginActivity后,查看setupViews的代码,第一是从intent中取值判断Activity有无进行动画过渡,如果进行动画过渡,那么在动画结束后用EventBus结束闪屏Activity
window.sharedElementEnterTransition.addListener(object : SimpleTransitionListener() {
override fun onTransitionEnd(transition: Transition) {
val event = FinishActivityEvent()
event.activityClass = OpenSourceSplashActivity::class.java
EventBus.getDefault().post(event)
isTransitioning = false
fadeElementsIn()
}
})
接着fadeElementsIn()代码
/**
* 将LoginActivity的界面元素使用淡入的方式显示出来。
*/
private fun fadeElementsIn() {
TransitionManager.beginDelayedTransition(loginLayoutBottom, Fade())
loginLayoutBottom.visibility = View.VISIBLE
TransitionManager.beginDelayedTransition(loginBgWallLayout, Fade())
loginBgWallLayout.visibility = View.VISIBLE
}
如同注释说的,进行动画的显示,如果是Android5.0以下版本和没有进行共享元素动画的时候,则直接把loginLayoutBottom和loginBgWallLayout设置View.VISIBLE,可以看到对应布局文件下这2个布局的属性代码,都是隐藏的:
android:visibility="invisible"
登录界面完整显示出来后,就是登录了,登录首先是检查手机号格式,这里不累述,接着是获取手机验证码,倒计时60秒,点击获取验证码后向后端发送网络请求。登录请求也是,根据登录请求的状态码判断登录状态。
when (status) {
0 -> {
hideSoftKeyboard()
// 处理登录成功时的逻辑,包括数据缓存,界面跳转等
saveAuthData(userId, token, TYPE_PHONE_LOGIN)
getUserBaseinfo()
}
10101 -> {
hideSoftKeyboard()
OpenSourceRegisterActivity.registerByPhone(this@OpenSourceLoginActivity, number, code)
loginInProgress(false)
}
else -> {
logWarn(TAG, "Login failed. " + GlobalUtil.getResponseClue(status, msg))
showToast(response.msg)
loginInProgress(false)
}
}
0表示登录成功,调用getUserBaseinfo()方法,对用户id,token等存入xml,并且启动MainActivity。
补充一下:登录和注册都是继承自AuthActivity
其中getUserBaseinfo()是发送网络请求,并对用户信息进行XML存储,其中forwardToMainActivity()方法是需要LoginActivity和RegisterActivity自己实现的
如果10101则表示手机号未注册,intent传入手机号,验证码和注册方式并跳转到OpenSourceRegisterActivity(此时LoginActivity没有Finish),OpenSourceRegisterActivity继承自RegisterActivity,可以看到RegisterActivity下setupViews对doRegister()的引用,而OpenSourceRegisterActivity的doRegister()指向sendPhoneRegisterRequest,该方法附带手机号和验证码POST到服务器,根据请求结果调用
handleRegisterCallback进行处理,
when (status) {
0 -> {
logDebug(TAG, "token is " + register.token + " , getAvatar is " + register.avatar)
val userId = register.userId
val token = register.token
saveAuthData(userId.toLong(), token, loginType)
registerSuccess()
}
10105 -> {
registerInProgress(false)
nicknameLayout.isErrorEnabled = true
nicknameLayout.error = GlobalUtil.getString(R.string.register_failed_nickname_is_used)
}
else -> {
logWarn(TAG, "Register failed. " + GlobalUtil.getResponseClue(status, register.msg))
showToast(register.msg)
finish()
}
根据状态码判断,注册成功调用getUserBaseinfo(看上边补充),而RegiestActivity的forwardToMainActivity跳转MainActivity,并采用EventBus结束LoginActivity,接着RegistActivity自己finish