From f52091dff5f2c6b67c6f7102dfa3371ef046f517 Mon Sep 17 00:00:00 2001 From: mertsimsek Date: Tue, 3 Mar 2020 14:00:32 +0300 Subject: [PATCH] Add attach() and detach() methods. --- .../iammert/tabscrollattacher/MainActivity.kt | 7 +- .../tabscrollattacherlib/TabScrollAttacher.kt | 109 ++++++++++-------- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/com/iammert/tabscrollattacher/MainActivity.kt b/app/src/main/java/com/iammert/tabscrollattacher/MainActivity.kt index 6393ac0..3c8a404 100644 --- a/app/src/main/java/com/iammert/tabscrollattacher/MainActivity.kt +++ b/app/src/main/java/com/iammert/tabscrollattacher/MainActivity.kt @@ -33,9 +33,14 @@ class MainActivity : AppCompatActivity() { * SETUP ATTACHER */ val indexOffsets = getCategoryIndexOffsets(categories) - TabScrollAttacher(tabLayout, recyclerView, indexOffsets) { + val attacher = TabScrollAttacher(tabLayout, recyclerView, indexOffsets) { scrollSmoothly() } + + attacher.attach() + + //attacher.detach() + } /** diff --git a/tabscrollattacherlib/src/main/java/com/iammert/tabscrollattacherlib/TabScrollAttacher.kt b/tabscrollattacherlib/src/main/java/com/iammert/tabscrollattacherlib/TabScrollAttacher.kt index 9f4e167..3e9d247 100644 --- a/tabscrollattacherlib/src/main/java/com/iammert/tabscrollattacherlib/TabScrollAttacher.kt +++ b/tabscrollattacherlib/src/main/java/com/iammert/tabscrollattacherlib/TabScrollAttacher.kt @@ -13,67 +13,78 @@ class TabScrollAttacher( configuration: Configuration.() -> Unit = {} ) { - private val layoutManager: LinearLayoutManager + private lateinit var layoutManager: LinearLayoutManager + + private lateinit var config: Configuration private var attacherState = AttacherState.IDLE - private val config: Configuration + private var isAttached = false + + private var scrollListener = object : RecyclerView.OnScrollListener() { + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + super.onScrolled(recyclerView, dx, dy) + + if (attacherState == AttacherState.TAB_SELECTED) { + return + } + + val isScrolling = dx != 0 || dy != 0 + if (attacherState == AttacherState.IDLE && isScrolling) { + attacherState = AttacherState.RECYCLERVIEW_SCROLLING + } + + val calculatedRecyclerViewItemPosition = when { + layoutManager.findLastVisibleItemPosition() == layoutManager.itemCount - 1 -> layoutManager.findLastVisibleItemPosition() + layoutManager.findFirstVisibleItemPosition() == 0 -> layoutManager.findFirstVisibleItemPosition() + else -> findMidVisibleRecyclerItemPosition() + } + + val tabIndex = getTabIndex(calculatedRecyclerViewItemPosition) + if (tabIndex != tabLayout.selectedTabPosition) { + tabLayout.getTabAt(tabIndex)?.select() + } + } + + override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { + super.onScrollStateChanged(recyclerView, newState) + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + attacherState = AttacherState.IDLE + } + } + } + + private var tabSelectedListener = object : SimpleTabSelectedListener() { + override fun onTabSelected(p0: TabLayout.Tab?) { + super.onTabSelected(p0) + if (attacherState != AttacherState.RECYCLERVIEW_SCROLLING) { + attacherState = AttacherState.TAB_SELECTED + val recyclerViewPosition = tabStartIndexOffsets[tabLayout.selectedTabPosition] + recyclerView.scrollToPosition(recyclerViewPosition, config.scrollMethod) + } + } + } init { require(recyclerView.layoutManager is LinearLayoutManager) { "Only LinearLayoutManager is supported." } layoutManager = recyclerView.layoutManager as LinearLayoutManager config = Configuration().apply(configuration) - observeRecyclerViewScroll() - observeTabLayoutSelection() } - private fun observeRecyclerViewScroll() { - recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { - override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { - super.onScrolled(recyclerView, dx, dy) - - if (attacherState == AttacherState.TAB_SELECTED) { - return - } - - val isScrolling = dx != 0 || dy != 0 - if (attacherState == AttacherState.IDLE && isScrolling) { - attacherState = AttacherState.RECYCLERVIEW_SCROLLING - } - - val calculatedRecyclerViewItemPosition = when { - layoutManager.findLastVisibleItemPosition() == layoutManager.itemCount - 1 -> layoutManager.findLastVisibleItemPosition() - layoutManager.findFirstVisibleItemPosition() == 0 -> layoutManager.findFirstVisibleItemPosition() - else -> findMidVisibleRecyclerItemPosition() - } - - val tabIndex = getTabIndex(calculatedRecyclerViewItemPosition) - if (tabIndex != tabLayout.selectedTabPosition) { - tabLayout.getTabAt(tabIndex)?.select() - } - } - - override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { - super.onScrollStateChanged(recyclerView, newState) - if (newState == RecyclerView.SCROLL_STATE_IDLE) { - attacherState = AttacherState.IDLE - } - } - }) + fun detach() { + if (isAttached) { + recyclerView.removeOnScrollListener(scrollListener) + tabLayout.removeOnTabSelectedListener(tabSelectedListener) + isAttached = false + } } - @SuppressLint("ClickableViewAccessibility") - private fun observeTabLayoutSelection() { - tabLayout.addOnTabSelectedListener(object : SimpleTabSelectedListener() { - override fun onTabSelected(p0: TabLayout.Tab?) { - super.onTabSelected(p0) - if (attacherState != AttacherState.RECYCLERVIEW_SCROLLING) { - attacherState = AttacherState.TAB_SELECTED - val recyclerViewPosition = tabStartIndexOffsets[tabLayout.selectedTabPosition] - recyclerView.scrollToPosition(recyclerViewPosition, config.scrollMethod) - } - } - }) + fun attach() { + if (isAttached.not()) { + recyclerView.addOnScrollListener(scrollListener) + tabLayout.addOnTabSelectedListener(tabSelectedListener) + isAttached = true + } } private fun findMidVisibleRecyclerItemPosition(): Int {