错误日志主要为下:
java.lang.IllegalArgumentException: parameter must be a descendant of this view
at android.view.ViewGroup.offsetRectBetweenParentAndChild(ViewGroup.java:4568)
at android.view.ViewGroup.offsetDescendantRectToMyCoords(ViewGroup.java:4505)
at android.view.ViewGroup$ViewLocationHolder.init(ViewGroup.java:6743)
at android.view.ViewGroup$ViewLocationHolder.obtain(ViewGroup.java:6680)
at android.view.ViewGroup$ChildListForAccessibility.init(ViewGroup.java:6638)
at android.view.ViewGroup$ChildListForAccessibility.obtain(ViewGroup.java:6606)
at android.view.ViewGroup.addChildrenForAccessibility(ViewGroup.java:1697)
at android.view.ViewGroup.onInitializeAccessibilityNodeInfoInternal(ViewGroup.java:2525)
...
...
...
研究这个错误很久,终于在stackoverflow找到了解决方案:
https://stackoverflow.com/questions/30585561/another-java-lang-illegalargumentexception-parameter-must-be-a-descendant-of-th
The problem was caused by adding a wrongly inflated header to two different listviews.
I inflated a view using listViewA as the parent and adding it to listViewB also. As such:
RelativeLayout listViewHeader = (RelativeLayout) inflater.inflate(R.layout.listviewheader, listViewA, false);
// Set some views
listViewA.addHeaderView(listViewHeader);
listViewB.addHeaderView(listViewHeader);
I fixed it by changing the above to the following:
RelativeLayout listViewHeaderA = (RelativeLayout) inflater.inflate(R.layout.listviewheader, listViewA, false);
RelativeLayout listViewHeaderB = (RelativeLayout) inflater.inflate(R.layout.listviewheader, listViewB, false);
listViewA.addHeaderView(listViewHeaderA);
listViewB.addHeaderView(listViewHeaderB);
As for reproducing the crash, the problem happened when Google Talk Back is turned on. Here is my take on the situation: Google Talk Back does text to speech on views that are in focus (either by touch or auto-focused). When it enters a screen with multiple views requesting focus, it reads the views according to a hierarchy/order.
If you have a layout (parent) with three views (children), Google Talk Back checks how the views are arranged and then reads them accordingly. For example, in a layout with three textview lined up horizontally, Google Talk Back may read the left textview first, then the middle one, then the one on the right.
In my case, I was inflating a header view with listViewA as the parent and adding that view to both listViewA and listViewB. When listViewBgains focus and Google Talk Back tries to interpret its children, it sees the header view is not a child of the list and throws the exception. This also happens if I inflate the header view with no parents (null).
大意为:
把一个viewA 作为ListViewA和ListViewB的headerView,当在ListViewB中操作viewA时,就会报这个错误,解决方案是:
为每一个ListView单独添加只属于本身的View,即:
将:
RelativeLayout listViewHeader = (RelativeLayout) inflater.inflate(R.layout.listviewheader, listViewA, false);
// Set some views
listViewA.addHeaderView(listViewHeader);
listViewB.addHeaderView(listViewHeader);
改为:
RelativeLayout listViewHeaderA = (RelativeLayout) inflater.inflate(R.layout.listviewheader, listViewA, false);
RelativeLayout listViewHeaderB = (RelativeLayout) inflater.inflate(R.layout.listviewheader, listViewB, false);
listViewA.addHeaderView(listViewHeaderA);
listViewB.addHeaderView(listViewHeaderB);