全局无侵入监听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)
}


上一篇下一篇

猜你喜欢

热点阅读