Skip to content

ShimmerLayout animation logic ignores parent visibility and detached from window state #77

@alexandrvj

Description

@alexandrvj

There are at least two problem cases with ShimmerLayout animation logic.

  1. If the ShimmerLayout has parent view/container and you hide parent view, animation logic inside ShimmerLayout doesn't stop. For example, we have some xml

<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_margin="8dp"
android:visibility="gone">

<io.supercharge.shimmerlayout.ShimmerLayout
    android:id="@+id/shimmer"
    app:shimmer_auto_start="true"
    style="@style/ShimmerLayout">

    <View
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_gravity="center_vertical|start"
        android:layout_marginLeft="16dp"
        android:background="@color/n7"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="16dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="64dp"
        android:layout_marginRight="32dp"
        android:background="@color/n7"/>
</io.supercharge.shimmerlayout.ShimmerLayout>

</androidx.cardview.widget.CardView>

then our ShimmerLayout will run recursivelly in startShimmerAnimation method, although we have not even shown it to the user.

  1. More than that it leads to memory leak when using Activity#recreate method:
    a) ShimmerLayout#startShimmerAnimation subscribes to ViewTreeObserver#onPreDraw to detect own width;
    b) ShimmerLayout don't stop animation logic when parent view becomes hidden or the ShimmerLayout is detached from the window.;
  • com.example.app.MyFragment has leaked:
  • static WindowManagerGlobal.sDefaultWindowManager
  • ↳ WindowManagerGlobal.mRoots
  • ↳ ArrayList.elementData
  • ↳ array Object[].[0]
  • ↳ ViewRootImpl.!(mAttachInfo)!
  • ↳ View$AttachInfo.!(mTreeObserver)!
  • ↳ ViewTreeObserver.!(mOnPreDrawListeners)!
  • ↳ ViewTreeObserver$CopyOnWriteArray.!(mData)!
  • ↳ ArrayList.!(elementData)!
  • ↳ array Object[].!([1])!
  • ↳ ShimmerLayout$1.!(this$0)! (anonymous implementation of android.view.ViewTreeObserver$OnPreDrawListener)
  • ↳ ShimmerLayout.mContext
  • ↳ MainActivity.navigationController
  • ↳ DefaultBottomBarController.adapter
  • ↳ CachePagerAdapter.mCurrentPrimaryItem
  • ↳ MyFragment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions