package com.xw.common.base
|
|
import android.annotation.SuppressLint
|
import android.content.Intent
|
import android.content.pm.ActivityInfo
|
import android.os.Bundle
|
import android.view.LayoutInflater
|
import android.view.View
|
import android.view.WindowManager
|
import android.view.inputmethod.InputMethodManager
|
import androidx.activity.OnBackPressedCallback
|
import androidx.appcompat.app.AppCompatActivity
|
import androidx.core.view.ViewCompat
|
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.updatePadding
|
import androidx.databinding.ViewDataBinding
|
import androidx.lifecycle.ViewModelProvider
|
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
import com.blankj.utilcode.util.BarUtils
|
import com.xw.common.R
|
import com.xw.common.utils.AppGlobals
|
import com.xw.common.utils.BindUtils.enableBindingLogging
|
import com.xw.common.utils.ScreenAdaptationUtil
|
import java.lang.reflect.ParameterizedType
|
|
abstract class BaseActivity<V : ViewDataBinding, VM : BaseViewModel> : AppCompatActivity() {
|
|
var TAG = "zmc-${this.javaClass.simpleName}"
|
|
lateinit var viewModel: VM
|
lateinit var binding: V
|
|
private var dialog: LoadingDialog? = null
|
|
@SuppressLint("SourceLockedOrientationActivity")
|
override fun onCreate(savedInstanceState: Bundle?) {
|
ScreenAdaptationUtil.setCustomDensity(this, AppGlobals.getApplication())
|
BarUtils.transparentStatusBar(this)
|
BarUtils.setStatusBarLightMode(this, true)
|
//统一设置activity竖屏
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
super.onCreate(savedInstanceState)
|
|
// 在 setContentView 之前强制设置
|
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
|
|
// 或者同时设置多个模式
|
window.setSoftInputMode(
|
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN or
|
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
|
)
|
window.addFlags(
|
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED //锁屏状态下显示
|
or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD //解锁
|
or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON //保持屏幕长亮
|
or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON //打开屏幕
|
)
|
|
initDataBinding()
|
applyNavigationBarPadding()// 处理底部导航栏适配
|
initViewModel()
|
initUiObservable()
|
myCreate(savedInstanceState)
|
initData()
|
setListener()
|
setObservable()
|
init()
|
|
// 在 Activity 中使用 OnBackPressedDispatcher
|
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
override fun handleOnBackPressed() {
|
onBackPressedHandel()
|
}
|
})
|
}
|
|
/**
|
* 自动适配底部导航栏/手势条高度
|
* 给根视图添加底部内边距,避免内容被遮挡
|
*/
|
protected open fun applyNavigationBarPadding() {
|
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
|
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars())
|
onApplyNavigationBarInsets(view, insets.bottom)
|
WindowInsetsCompat.CONSUMED
|
}
|
}
|
/**
|
* 子类可覆盖此方法自定义底部内边距处理
|
* @param bottomInset 底部导航栏/手势条高度(像素)
|
*/
|
protected open fun onApplyNavigationBarInsets(view: View, bottomInset: Int) {
|
view.updatePadding(bottom = bottomInset)
|
}
|
|
open fun onBackPressedHandel() {
|
// 处理返回事件,使用 OnBackPressedDispatcher 替代已弃用的 onBackPressed 方法
|
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
if (null != currentFocus) imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0) //隐藏软键盘
|
overridePendingTransition(R.anim.activity_close_open, R.anim.activity_close_exit)
|
finish()
|
}
|
|
/**
|
* 创建dataBingding,并自动设置布局
|
*/
|
private fun initDataBinding() {
|
val dbClass = genericTypeBinding()
|
val method = dbClass.getMethod("inflate", LayoutInflater::class.java)
|
binding = method.invoke(null, layoutInflater) as V
|
setContentView(binding.root)
|
binding.enableBindingLogging()
|
}
|
|
private fun initViewModel() {
|
viewModel = createViewModel()
|
binding.setVariable(getBindingVariable(), viewModel)
|
binding.lifecycleOwner = this
|
|
//让ViewModel拥有View的生命周期感应
|
lifecycle.addObserver(viewModel)
|
}
|
|
private fun initUiObservable() {
|
viewModel.dialogEvent.observe(this) {
|
if (it == "dismiss") {
|
dismissDialog()
|
} else {
|
showDialog(it)
|
}
|
}
|
viewModel.onBackEvent.observe(this) {
|
if (it == "back") {
|
onBackPressed()
|
} else if (it == "finish") {
|
finish()
|
}
|
}
|
viewModel.closeEvent.observe(this) {
|
if (it == "close") {
|
closeKeyboard()
|
} else if (it == "hide") {
|
hideKeyboard()
|
}
|
}
|
viewModel.startActivityEvent.observe(this) { params ->
|
val clz = params["CLASS"] as Class<*>
|
var bundle: Bundle? = null
|
try {
|
bundle = params["BUNDLE"] as Bundle
|
} catch (e: Exception) {
|
|
}
|
if (params["requestCode"] == null) {
|
startActivity(clz, bundle)
|
return@observe
|
}
|
val mIntent = Intent(this@BaseActivity, clz)
|
bundle?.let {
|
mIntent.putExtras(it)
|
}
|
startActivityForResult(mIntent, params["requestCode"] as Int)
|
overridePendingTransition(R.anim.activity_open_enter, R.anim.activity_open_exit)
|
}
|
}
|
|
/**
|
* 创建viewModel
|
*/
|
private fun createViewModel(): VM {
|
return ViewModelProvider(this).get(genericTypeViewModel())
|
}
|
|
/**
|
* 获取当前类泛型viewmodel的Class类型
|
* @return
|
*/
|
private fun genericTypeViewModel(): Class<VM> {
|
return (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<VM>
|
}
|
|
private fun genericTypeBinding(): Class<V> {
|
return (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<V>
|
}
|
|
|
open fun setListener() {}
|
|
open fun setObservable() {}
|
|
open fun myCreate(savedInstanceState: Bundle?) {}
|
|
open fun initData() {}
|
|
open fun init() {}
|
|
/** 获取参数Variable */
|
protected abstract fun getBindingVariable(): Int
|
|
/**
|
* 跳转页面
|
*
|
* @param clz 所跳转的目的Activity类
|
* @param bundle 跳转所携带的信息
|
*/
|
fun startActivity(clz: Class<*>?, bundle: Bundle? = null) {
|
val intent = Intent(this, clz)
|
bundle?.let {
|
intent.putExtras(it)
|
}
|
startActivity(intent)
|
overridePendingTransition(R.anim.activity_open_enter, R.anim.activity_open_exit)
|
}
|
|
fun startActivityForResult(clz: Class<*>?, code: Int, bundle: Bundle? = null) {
|
val intent = Intent(this, clz)
|
bundle?.let {
|
intent.putExtras(it)
|
}
|
startActivityForResult(intent, code)
|
overridePendingTransition(R.anim.activity_open_enter, R.anim.activity_open_exit)
|
}
|
|
var inputMethodManager: InputMethodManager? = null
|
|
open fun closeKeyboard() {
|
if (window.attributes.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) {
|
if (currentFocus != null) {
|
if (inputMethodManager == null) {
|
inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
}
|
inputMethodManager?.hideSoftInputFromWindow(
|
currentFocus!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS
|
)
|
}
|
}
|
}
|
|
private fun hideKeyboard() {
|
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
|
}
|
|
// 关闭默认局部刷新动画
|
fun closeRvAnim(rv: RecyclerView) {
|
rv.itemAnimator?.addDuration = 0
|
rv.itemAnimator?.changeDuration = 0
|
rv.itemAnimator?.moveDuration = 0
|
rv.itemAnimator?.removeDuration = 0
|
(rv.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
}
|
|
fun showDialog(title: String = "加载中...") {
|
if (isFinishing) {
|
return
|
}
|
if (dialog != null) {
|
dialog!!.show(title)
|
} else {
|
dialog = LoadingDialog(this)
|
dialog!!.show(title)
|
}
|
}
|
|
fun dismissDialog() {
|
if (dialog != null && dialog!!.isShowing) {
|
dialog!!.dismiss()
|
}
|
}
|
}
|