class ScreenMainGridManager(private val mAdapter: BaseAdapter, context: Context) :
GridLayoutManager(context, 4) {
private val marginStart = context.resources.getDimension(R.dimen.common_dp_54)
init {
spanSizeLookup = object : SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
val viewType = mAdapter.getItemViewType(position)
return when (viewType) {
ViewType.TITLE.value, ViewType.BANNER.value -> 4
else -> 1
}
}
}
}
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
return when (direction) {
View.FOCUS_LEFT -> {
findLeftFocusView(focused) ?: super.onInterceptFocusSearch(focused, direction)
}
View.FOCUS_RIGHT -> {
var isRightFocus = false
findRecyclerView(focused)?.let {
findRootView(focused)?.let { root ->
val position = it.getChildAdapterPosition(root)
if (position > 0 && position + 1 < itemCount) {
val viewType = mAdapter.getItemViewType(position + 1)
if (viewType == ViewType.TITLE.value) {
isRightFocus = true
}
} else if (position + 1 == itemCount) {
isRightFocus = true
}
}
}
if (isRightFocus) focused else super.onInterceptFocusSearch(focused, direction)
}
else -> super.onInterceptFocusSearch(focused, direction)
}
}
private fun findLeftFocusView(focused: View): View? {
findRecyclerView(focused)?.let {
val location = IntArray(2)
focused.getLocationOnScreen(location)
if (location[0] < marginStart) {
return focused
}
}
return null
}
private fun findRecyclerView(focused: View): RecyclerView? {
var parent: ViewParent? = focused.parent
for (i in 0 until 2) {
if (parent is RecyclerView) break
parent = parent?.parent
}
return parent as? RecyclerView
}
/** item root view */
private fun findRootView(focused: View): View? {
var result: View? = focused
var parent = focused.parent
for (i in 0 until 2) {
if (parent is RecyclerView) {
return result
}
result = parent as? View
parent = parent?.parent
}
return result
}
override fun onRequestChildFocus(
parent: RecyclerView,
state: RecyclerView.State,
child: View,
focused: View?
): Boolean {
val position = parent.getChildAdapterPosition(child)
scrollToPosition(position)
return super.onRequestChildFocus(parent, state, child, focused)
}
override fun onFocusSearchFailed(
focused: View,
focusDirection: Int,
recycler: RecyclerView.Recycler,
state: RecyclerView.State
): View? {
return when (focusDirection) {
View.FOCUS_UP -> {
if (focused.parent.parent is RecyclerView) {
val position = (focused.parent as? View)?.let { getPosition(it) } ?: -1
if (position < 0) {
super.onFocusSearchFailed(focused, focusDirection, recycler, state)
} else {
val item = mAdapter.getItem(position)
if (item is MainBannerItem || item is MeAddItem) {
focused.rootView.findViewById<View>(R.id.btn_myself)
?: focused.rootView.findViewById<View>(R.id.btn_back)
} else {
scrollToPosition(0)
super.onFocusSearchFailed(focused, focusDirection, recycler, state)
}
}
} else {
focused.rootView.findViewById<View>(R.id.btn_myself)
}
}
else -> super.onFocusSearchFailed(focused, focusDirection, recycler, state)
}
}
}