该异常抛出有一定的前提:
compile 'com.android.support:recyclerview-v7:23.0.0'
RecyclerView的23版本没有问题, 24或25版本会抛出异常。
23以上的版本中RecyclerView中的代码已经不相同。
而23及下的RecyclerView中没有isPreferredNextFocus方法,其focusSearch()方法内部也不一样。高版本在focusSearch()方法内return后调用了isPreferredNextFocus()。
25版本的RecyclerView.focusSearch()
public View focusSearch(View focused, int direction) {
View result = mLayout.onInterceptFocusSearch(focused, direction);
if (result != null) {
return result;
}
final boolean canRunFocusFailure = mAdapter != null && mLayout != null
&& !isComputingLayout() && !mLayoutFrozen;
final FocusFinder ff = FocusFinder.getInstance();
if (canRunFocusFailure
&& (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD)) {
//此处省略N行........
if (needsFocusFailureLayout) {
//此处省略N行........
}
} else {
//此处省略N行.........
}
return isPreferredNextFocus(focused, result, direction)
? result : super.focusSearch(focused, direction);
}
需先判断isPrfeeredNextFocus是否为true,异常在该方法内部调到的ViewGroup内部的offsetRectBetweenParentAndChild抛出异常
23版本的ReyclerView.focusSearch()
@Override
public View focusSearch(View focused, int direction) {
View result = mLayout.onInterceptFocusSearch(focused, direction);
if (result != null) {
return result;
}
final FocusFinder ff = FocusFinder.getInstance();
result = ff.findNextFocus(this, focused, direction);
if (result == null && mAdapter != null && mLayout != null && !isComputingLayout()
&& !mLayoutFrozen) {
eatRequestLayout();
result = mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
resumeRequestLayout(false);
}
return result != null ? result : super.focusSearch(focused, direction);
}