LoginSignup
0
0

[Android] RecyclerView スクロール時にビViewPagerを非活性化

Last updated at Posted at 2024-05-09

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0