android-recyclerviewandroid-flexboxlayout

FlexboxLayoutManager item flickering on scrolling of another Recycler View


I have 2 recyclerView, RecyclerView 1, having layoutManager with app:layoutManager="com.google.android.flexbox.FlexboxLayoutManager" & another RecyclerView 2, having app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager".

The first recyclerview item is flickering when scrolling on another recyclerView. It's working fine when item count of RecyclerView 1 is less than 6 or 7.

Please check the video link for the issue reference(0:18s - 0:46s): https://drive.google.com/file/d/17_wa3vd5H7QKh0fgj6Sh310ZNlt2TeG1/view?usp=sharing

Please find the code-snippet below:

activity_personal_activities.xml

<ScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_0"
            android:fillViewport="true"
            app:layout_constraintBottom_toTopOf="@+id/btnSave"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tvHeaderTitle">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                
                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/rvConditionsSelected"
                    android:layout_width="@dimen/dp_0"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/dp_12"
                    android:layout_marginBottom="@dimen/dp_20"
                    android:orientation="horizontal"
                    android:paddingStart="@dimen/dp_24"
                    android:paddingEnd="@dimen/dp_0"
                    app:layoutManager="com.google.android.flexbox.FlexboxLayoutManager"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintHeight_max="@dimen/dp_100"
                    app:layout_constraintHorizontal_bias="0"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:spanCount="2"
                    tools:itemCount="4"
                    tools:listitem="@layout/inflate_conditions_selected" />

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/rvConditions"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_0"
                    android:layout_marginTop="@dimen/dp_7"
                    android:orientation="vertical"
                    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/rvConditionsSelected"
                    tools:itemCount="5"
                    tools:listitem="@layout/inflate_conditions" />


            </androidx.constraintlayout.widget.ConstraintLayout>
        </ScrollView>

Setting up adapter:

(bViewDataBinding?.rvConditionsSelected?.itemAnimator as? DefaultItemAnimator)?.supportsChangeAnimations = false
bViewDataBinding?.rvConditionsSelected?.adapter = adapter

ScrollToPosition of RecyclerView 1, On Adding new Item

bViewDataBinding?.rvConditionsSelected?.scrollToPosition(adapterList.size - 1)

Solution

  • I found the root cause of the flicker issue & the Problem was with the first recyclerView height. So I fixed this issue by adding a fixed height initially. If you see in my query, recyclerView height is android:layout_height="@dimen/dp_0" & app:layout_constraintHeight_max="@dimen/dp_100" that is causing the flicker on the FlaxBoxLayoutManager recyclerView.

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvConditionsSelected"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_36"
        android:layout_marginTop="@dimen/dp_12"
        android:orientation="horizontal"
        app:layoutManager="com.google.android.flexbox.FlexboxLayoutManager"
        android:paddingStart="@dimen/dp_24"
        android:paddingEnd="@dimen/dp_0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/cvSearch"
        tools:itemCount="4"
        tools:listitem="@layout/inflate_conditions_selected" />
    

    So, I'm changing the height of recyclerView programmatically

    override fun updateRecyclerViewHeight() {
        val flexSize = (bViewDataBinding?.rvConditionsSelected?.layoutManager as? FlexboxLayoutManager)?.flexLinesInternal?.size
                ?: return
        when (flexSize) {
            3 -> changeRecyclerViewHeight(SizeUtils.dp2px(this,100F))
            2 -> changeRecyclerViewHeight(SizeUtils.dp2px(this,72F))
            1 -> changeRecyclerViewHeight(SizeUtils.dp2px(this,36F))
        }
    }
    
    override fun changeRecyclerViewHeight(height: Int) {
        val params = bViewDataBinding?.rvConditionsSelected?.layoutParams
        params?.height = height
        bViewDataBinding?.rvConditionsSelected?.layoutParams = params
    }