通过反射获取view再layout里面设置的onclick属性值

   /**
         * 通过反射,获取View的在res/Layout布局中声明的onClick属性名称
         * 但是通过databinding方式设置的值获取不到
         * 
         */
        fun getViewClickListenerName(view: View?): String? {
            var clickName: String? = null
            try {
                // get the nested class `android.view.View$ListenerInfo`
                val listenerInfoField: Field? = View::class.java.getDeclaredField("mListenerInfo")
                listenerInfoField?.isAccessible = true
                val myViewListenerInfo = listenerInfoField?.get(view)

                // get the field mOnClickListener, that holds the listener and cast it to a listener
                val onClickListener: Field? =
                    myViewListenerInfo?.javaClass?.getDeclaredField("mOnClickListener")
                onClickListener?.isAccessible = true
                val myClickListener = onClickListener?.get(myViewListenerInfo)

                val fields = myClickListener?.javaClass?.declaredFields
                fields?.apply {
                    for (field in fields) {
                        if (field.name.equals("mMethodName")) {
                            //get the field mMethodName
                            val mMethodName: Field? =
                                myClickListener.javaClass.getDeclaredField("mMethodName")
                            mMethodName?.isAccessible = true
                            //get my MethodName
                            val myMethodName = mMethodName?.get(myClickListener)
                            clickName = myMethodName as String?
                        }
                    }
                }

            } catch (e: ClassNotFoundException) {
                e.printStackTrace()
            } catch (e: IllegalAccessException) {
                e.printStackTrace()
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return clickName
        }

 

 

同上一个方法:

  /**
         * 通过反射,获取View的在res/Layout布局中声明的onClick属性名称
         *
         */
        private fun getOnClickName(view: View?): String {
            if (view == null) {
                throw NullPointerException("view == null")
            }
            var Name = ""

            // 反射 View.mListenerInfo.mOnClickListener.val$handlerName
            try {
                val mListenerInfo = getSubField(view, "mListenerInfo")
                val mOnClickListener = getSubField(mListenerInfo, "mOnClickListener")
                val handlerName = getSubField(mOnClickListener, "mMethodName")
                Name = handlerName as String
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return Name
        }


        /**
         * 反射获取obj的成员变量fieldName(成员变量名获取,可在调试时动态查看)
         */
        private fun getSubField(obj: Any?, fieldName: String): Any? {
            if (obj == null) {
                throw NullPointerException("obj == null")
            }

            var subObj: Any? = null
            try {
                val field: Field? = obj.javaClass.getDeclaredField(fieldName)    // 获取成员变量对应的Field方法
                field?.isAccessible = true    // 设置为可访问
                subObj = field?.get(obj)    // 通过Field方法从Object中提取子变量
            } catch (ex: Exception) {
                ex.printStackTrace()
            }

            return subObj
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章