一、背景
在開發過程中,能夠快速找到具體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具體使用
image.png
2.3產出日志
image.png
image.png
三、結論
該方法還有待優化