一、背景
在开发过程中,能够快速找到具体view对于我们效率的提升是很有帮助的,这里推荐一个快速定位到view id的工具Weditor,这个工具可以根据视图得到具体的view Id,详细的使用教程请看[Mac安装WEditor教程 - 简书 (jianshu.com)
],在无障碍设配开发过程中,我们需要对具体的view设置是否支持无障碍能力,但是对于复杂的工程,由于嵌套层级过深,有时还存在重复覆盖问题,这时weditor就不好使了,当我们查询具体的view不能聚焦的时候,需要知道点击事件传递到具体到哪一层,方便我们解决问题,在此背景下激发了我开发这个工具类的想法
二、具体代码
2.1具体类
class AccessibilityFindViewIdDelegate(private val context: Context) : View.AccessibilityDelegate() {
/**
* 设置Activity页面中View的事件监听
*
* @param activity
*/
public fun setTracker(activity: Activity) {
// 找到根路径的View
val contentView = activity.findViewById<FrameLayout>(android.R.id.content)
if (contentView != null) {
setViewTracker(contentView, null)
}
}
/**
* 设置Fragment页面中View的事件监听
*
* @param fragment
*/
public fun setTracker(fragment: Fragment) {
val contentView = fragment.getView()
if (contentView != null) {
setViewTracker(contentView, fragment)
}
}
/**
* 设置View上的事件监听
*
* @param view
*/
public fun setTracker(view: View?) {
if (view != null) {
setViewTracker(view, null)
}
}
/**
* 判断view是否需要埋点,目前默认只要可以点击的都是true
*
* @param view
* @return
*/
private fun needTracker(view: View): Boolean {
return true
}
/**
* 对每个View添加埋点的监听
*
* @param view
* @param fragment
*/
private fun setViewTracker(view: View, fragment: Fragment?) {
if (needTracker(view)) {
if (fragment != null) {
view.setTag(1024, fragment)
}
view.accessibilityDelegate = this
}
if (view is ViewGroup) {
val childCount = view.childCount
var index = 0
while (index < childCount) {
setViewTracker(view.getChildAt(index), fragment)
index++
}
view.setOnHierarchyChangeListener(object : ViewGroup.OnHierarchyChangeListener {
override fun onChildViewAdded(parent: View, child: View) {
setTracker(parent)
}
override fun onChildViewRemoved(parent: View, child: View) {
setTracker(parent)
}
})
view.setAccessibilityDelegate(this)
}
}
override fun sendAccessibilityEvent(host: View?, eventType: Int) {
super.sendAccessibilityEvent(host, eventType)
if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_ENTER && host != null) {
var name: String? = null
var parentName: String? = null
var namePackageName: String? = null
var parentNamePackageName: String? = null
try {
name = context.resources.getResourceEntryName(host.id)
val parentViewGroup = host.parent
if (parentViewGroup is ViewGroup) {
parentName = context.resources.getResourceEntryName(parentViewGroup.id)
parentNamePackageName =
context.resources.getResourcePackageName(parentViewGroup.id)
}
namePackageName = context.resources.getResourcePackageName(host.id)
} catch (e: Exception) {
}
Log.d(
"FindViewIdDelegate",
"className:${host} name:${name} parent:$parentName packgeName:${namePackageName} parentNamePackageName:$parentNamePackageName"
)
}
}
}
2.2具体使用
2.3产出日志
三、结论
该方法还有待优化