ViewPager非活性化
ViewPagerに 特定のRecyclerViewがある部分で他のタブに移動しないように、ViewPagerの動きを無効にする必要がありました。
そのサンプルコードはメインアクティビティ内でリサイクラービューをフラグメントに実装したが
フラグメント内のフラグメントはIncludeで表現されている
ViewPagerがタッチされると、そのタッチイベントのx、y座標を取得し、その座標が特定のRecyclerViewの領域内にあるかを確認して、ViewPagerの機能を無効にし、タッチが終了したらスワイプ機能を再度有効にするようにGitHubにコメントで記載していましたが、
サンプルではアクティビティでViewPagerのインターフェイスを設定し、onScrollメソッドが呼ばれるかどうかを決定し、リサイクラービューがスクロールされている間はViewPagerのスワイプを無効にします。
ViewPager
MainActivity.kt
class MainActivity : AppCompatActivity(), OnRecyclerViewScrollListener {
private lateinit var binding: ActivityMainBinding
private var viewPagerFragment: ViewPagerFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.viewPager.adapter = ViewPagerAdapter(supportFragmentManager)
binding.tabLayout.setupWithViewPager(binding.viewPager)
binding.tabLayout.getTabAt(0)?.text = "ViewPager"
binding.tabLayout.getTabAt(1)?.text = "Fragment"
}
override fun onScroll(isScrolling: Boolean) {
binding.viewPager.isSwipeEnabled = !isScrolling
}
fun disableSwipe() {
binding.viewPager.isSwipeEnabled = false
}
fun enableSwipe() {
binding.viewPager.isSwipeEnabled = true
}
}
-
onScroll
インターフェイスのコールバックメソッドで、リサイクラービューがスクロールされると呼ばれ、リサイクラービューがスクロール中であればViewPagerのスワイプを無効にし、スクロールしていない場合はViewPagerのスワイプを有効にします。 -
disableSwipe
,enableSwipe
これらのメソッドは、ViewPagerのスワイプを無効または有効にする機能で、リサイクラービューがスクロールされる時にViewPagerのスワイプを制御するために使用されます。
RecyclerView
ViewPagerFragment.kt
class ViewPagerFragment : BaseFragment<FragmentViewpagerBinding>(R.layout.fragment_viewpager) {
private var scrollListener: OnRecyclerViewScrollListener? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val top: Array<Int> = arrayOf(
R.drawable.first,
R.drawable.second,
R.drawable.qwe
)
val bottom: Array<Int> = arrayOf(
R.drawable.ujm,
R.drawable.fifth,
R.drawable.asd
)
val topAdapter = TopAdapter(top)
binding.TopRecyclerViewId.adapter = topAdapter
binding.TopRecyclerViewId.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
val bottomAdapter = BottomAdapter(bottom)
binding.BottomRecyclerViewId.adapter = bottomAdapter
binding.BottomRecyclerViewId.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
binding.TopRecyclerViewId.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
// RecyclerViewがスクロール時にViewPagerを非活性化
if (newState != RecyclerView.SCROLL_STATE_IDLE) {
(activity as? MainActivity)?.disableSwipe()
} else {
// RecyclerViewがスクロールしない時ViewPagerを活性化
(activity as? MainActivity)?.enableSwipe()
}
}
})
}
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is OnRecyclerViewScrollListener) {
scrollListener = context
}
}
override fun onDetach() {
super.onDetach()
scrollListener = null
}
}
-
scrollListener
リサイクラービューがスクロールされる際に呼び出されるコールバックメソッドを定義し -
addOnScrollListener
ソッド内でRecyclerViewがスクロール中の場合はViewPagerのスワイプを無効にしてスワイプを防ぎ、RecyclerViewがスクロールされていない場合はViewPagerのスワイプが再び有効になります。 -
onAttach
フラグメントがアクティビティに接続される際に呼び出されるコールバックメソッドで、アクティビティがOnRecyclerViewScrollListenerインターフェイスを実装していれば、scrollListener変数にアクティビティの参照を保存します。 -
onDetach
フラグメントがアクティビティから分離される際に呼び出されるコールバックメソッドで、scrollListener変数をnullに設定して参照を解除します。
Adapter
ViewPager.Adapter
class ViewPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
private val fragments = listOf(
ViewPagerFragment(),
SecondFragment()
)
override fun getItem(position: Int): Fragment {
return fragments[position]
}
override fun getCount(): Int {
return fragments.size
}
}
- フラグメントアダプターでViewPagerを設定します。
GitHub : https://github.com/GEUN-TAE-KIM/DisableRecycerView_ViewPager_Sample.git