0

I have been searching to make the recyclerview Carousel so that first item populates again when the last item is visible and it keep on showing again and again. Now I know this answer is already answered here, and here but both these answer didnt solve my problem. Although number of items increased but the fragment which are items in recyclerview do not show anything.

I am inflating fragments as an items for RecyclerView which is nested in a ViewPager. The accepted answers hasnt been able to solve my problem.

Code: RecyclerViewAdapterClass

fun initialize(scrollableData: ArrayList<ScrollableData>, activity: AppCompatActivity) {
        this.scrollableData = scrollableData
        this.activity = activity
    }

    override fun getItemCount() = scrollableData.size

    override fun getItemViewType(position: Int): Int {
        return scrollableData[position].index
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseHolder {

        when (viewType) {
            ScrollableItems.ABC -> {
                val view = parent.inflate(R.layout.view_module_abc, false)
                return ABCViewHolder(view, abcPresenterImpl, activity)
            }

            ScrollableItems.DEF -> {
                val view = parent.inflate(R.layout.view_module_def, false)
                return DEFViewHolder(view, defControlPresenter, activity)
            }

            else -> {
                val view = parent.inflate(R.layout.view_module_ghi, false)
                return GHIViewHolder(view, GHIModulePresenter, activity)
            }
        }
    }

    override fun onBindViewHolder(holder: BaseHolder, position: Int) {
        holder.bindView()
    }

and HomeActivity#setupRecyclerView(...)

private fun setupRecyclerView(scrollableDataList: ArrayList<ScrollableData>) {
        linearLayoutManager = CustomLinearLayoutManager(applicationContext, LinearLayout.HORIZONTAL, !DeviceConfig.instance!!.isRegularDevice)
        recycler_view.layoutManager = linearLayoutManager
        recycler_view.adapter = mainScreenAdapter

        mainScreenAdapter.initialize(scrollableDataList, this)
        recycler_view.setHasFixedSize(true);
        GravityPagerSnapHelper(if (DeviceConfig.instance!!.isRegularDevice) Gravity.START else Gravity.END, true, this).attachToRecyclerView(recycler_view)
        recyclerViewScrollListener()
    }

and CustomLinearLayoutManager

class CustomLinearLayoutManager(context: Context, orientation: Int, reverseLayout: Boolean)
    : LinearLayoutManager(context, orientation, reverseLayout) {

    var isScrollEnabled = true

    override fun canScrollHorizontally(): Boolean {
        return isScrollEnabled && super.canScrollHorizontally()
    }

    override fun canScrollVertically(): Boolean {
        return isScrollEnabled && super.canScrollVertically()
    }
}

Please help me resolve this.

Ahmed S. Durrani
  • 1,535
  • 2
  • 17
  • 41

1 Answers1

0

So after extensive searching, found this solution.

So this is what I did

RecyclerViewAdapterClass

  fun initialize(scrollableData: ArrayList<ScrollableData>, activity: AppCompatActivity) {
            this.scrollableData = scrollableData
            this.activity = activity
            list = /*listOf(scrollableData.last()) +*/ scrollableData + listOf(scrollableData.first()) //this is very important
            }
    ...
      override fun getItemViewType(position: Int): Int {
        return list[position %  list.size].index
    }

HomeActivity#setupRecyclerView(...)

mainScreenAdapter.itemCount.takeIf { it > 1 }
                ?.apply {
                    onScrollListener = OnScrollListener(
                            mainScreenAdapter.itemCount,
                            linearLayoutManager
                    ) {
                       //some code here
                    }
                    recycler_view.addOnScrollListener(onScrollListener)
                    recycler_view.scrollToPosition(0)
                }

OnScrollListener

internal class OnScrollListener(val itemCount: Int, val layoutManager: LinearLayoutManager,
                                    val stateChanged: (Int) -> Unit) : RecyclerView.OnScrollListener() {
        var isLooping = false
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView!!, dx, dy)
            val firstItemVisible = layoutManager.findFirstCompletelyVisibleItemPosition()

            if (firstItemVisible > 0 && firstItemVisible % (itemCount - 1) == 0) {
                // When position reaches end of the list, it sho    uld go back to the beginning
                isLooping = true
                recyclerView?.scrollToPosition(0)
            } /*else if (firstItemVisible == 0) {
                // When position reaches beginning of the list, it should go back to the end
                recyclerView?.scrollToPosition(itemCount-1)
            }*/
        }

        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView!!, newState)
            var loop = newState
            if (isLooping) {
                loop = 100
                isLooping = false
            }
            stateChanged(loop)
        }
    }

Ref: https://github.com/tomoima525/CirculerAutoScrollingRecyclerView

Ahmed S. Durrani
  • 1,535
  • 2
  • 17
  • 41