全局无侵入监听Activity的事件分发
2020-12-23 本文已影响0人
柒_世
全局无侵入监听Activity的事件分发
object TouchEventWatcherUtil {
private var isInited = false
fun init(application: Application, touchCallback: OnTouchEventCallback) {
if (!isInited) {
val decorViewLifecycle = DecorViewLifecycle(touchCallback)
application.registerActivityLifecycleCallbacks(decorViewLifecycle)
isInited = true
}
}
}
internal class DecorViewLifecycle(private var touchCallback: OnTouchEventCallback? = null)
: Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {
val decorViewGroup = activity.window.decorView as ViewGroup?
decorViewGroup?.let {
if (decorViewGroup.childCount > 0 && !isReplace(decorViewGroup)) {
val proxyFrameLayout = ProxyContentLayout(activity, touchCallback)
val size = decorViewGroup.childCount
for (i in 0 until size) {
val view = decorViewGroup.getChildAt(i)
val lp = view.layoutParams
if (view != null) {
decorViewGroup.removeView(view)
proxyFrameLayout.addView(view, lp)
}
}
//替换掉DecorView原有的contentParent容器
decorViewGroup.addView(proxyFrameLayout)
}
}
}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
private fun isReplace(parentView: ViewGroup): Boolean {
val childCount = parentView.childCount
for (index in 0 until childCount) {
val childView = parentView.getChildAt(index)
if (childView::class.java == ProxyContentLayout::class.java) {
return true
}
}
return false
}
}
@SuppressLint("RestrictedApi")
internal class ProxyContentLayout(private val actvity: Activity, var touchCallback: OnTouchEventCallback? = null)
: ContentFrameLayout(actvity) {
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
touchCallback?.dispatchTouchEvent(ev)
return super.onInterceptTouchEvent(ev)
}
}
interface OnTouchEventCallback {
fun dispatchTouchEvent(event: MotionEvent)
}