christophesmet / android_maskable_layout

A library that easily allows you to mask layouts/viewgroups
Apache License 2.0
652 stars 145 forks source link

Low performance and UI lag when animating layer #7

Closed Morteza-Rastgoo closed 9 years ago

Morteza-Rastgoo commented 9 years ago

This is my code that has no lag with frame layout and i animate the inner views very well:

<FrameLayout
        android:id="@+id/maskFrameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.q42.android.scrollingimageview.ScrollingImageView
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:layout_gravity="bottom"
            scrolling_image_view:speed="0.25dp"
            scrolling_image_view:src="@drawable/world_map" />

        <FrameLayout
            android:id="@+id/frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:animateLayoutChanges="true">
        </FrameLayout>
    </FrameLayout>

But when i change it to maskable frame layout it gives whole UI a huge lag in animations:

<com.christophesmet.android.views.maskableframelayout.MaskableFrameLayout
        android:id="@+id/maskFrameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:mask="@drawable/contact_default_thumb"
        app:porterduffxfermode="SRC_IN">

        <com.q42.android.scrollingimageview.ScrollingImageView
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:layout_gravity="bottom"
            scrolling_image_view:speed="0.25dp"
            scrolling_image_view:src="@drawable/world_map" />

        <FrameLayout
            android:id="@+id/frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:animateLayoutChanges="true">
        </FrameLayout>
    </com.christophesmet.android.views.maskableframelayout.MaskableFrameLayout>

What is wrong that makes this lag appear in the UI?

christophesmet commented 9 years ago

Probably because the view is being invalidated every time. You can profile the code and see if there is a possiblity to cache the bitmap. Is there a sample I can run ? I don't think automatically caching and breaking the invalidate function would be a good idea. I suggest you look at bitmap shaders. Does this answer your question ?

Morteza-Rastgoo commented 9 years ago

This is a library that you can try here https://github.com/Q42/AndroidScrollingImageView

 <com.q42.android.scrollingimageview.ScrollingImageView
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:layout_gravity="bottom"
        scrolling_image_view:speed="0.25dp"
        scrolling_image_view:src="@drawable/world_map" />

and put it in your MaskableFrameLayout.

christophesmet commented 9 years ago

Well, thats normal. The view is invalidated each time, causing it to mask every time. Every time it scrolls it invalidates, the mask is being applied. So this will be very slow. Either decrease the amount of invalidates or use bitmap shaders.

Morteza-Rastgoo commented 9 years ago

I also use other views like Frame layout inside MaskableFrameLayout and i animate the views inside frame layout and animations are slow there too. The reason that i use this great library is that it makes it available to mask any view! is there a workaround that it perform better in animations? I am not familiar with shaders, how can i use an implementation?

christophesmet commented 9 years ago

Your animation will invalidate each time, causing a masking operation to be executed every time. Optimize your animation or profile your code.

Morteza-Rastgoo commented 9 years ago

I appreciate, If you can help me. I have two different views with different animations inside two maskable layout. In first one, i need to simulate a world map sphere movement in a loop so i used this lib(https://github.com/Q42/AndroidScrollingImageView):

 <com.q42.android.scrollingimageview.ScrollingImageView
    android:layout_width="match_parent"
    android:layout_height="250dp"
    android:layout_gravity="bottom"
    scrolling_image_view:speed="0.25dp"
    scrolling_image_view:src="@drawable/world_map" />

in second one i just have move and scale animations but i use this (https://github.com/daimajia/AndroidViewAnimations) library for implemented animations

  private void animateLines() {
    new Handler().postDelayed(() -> hideLineViews(false), 20);
    YoYo.with(Techniques.SlideInRight)
            .duration(lineAnimationDuration)
            .interpolate(new LinearInterpolator())
            .playOn(lines[1]);
    YoYo.with(Techniques.SlideInUp)
            .duration(lineAnimationDuration)
            .interpolate(new LinearInterpolator())
            .playOn(lines[0]);
}

private void animateExtensions() {
    new Handler().postDelayed(() -> hideExtensionViews(false), 40);
    for (View v : extensions) {
        YoYo.with(Techniques.ZoomIn)
                .duration(lineAnimationDuration)
                .interpolate(new LinearInterpolator())
                .playOn(v);
    }
}

What is your suggestion?

christophesmet commented 9 years ago

Use bitmap shaders. You are masking the view each time is animates. That is really cpu intensive. Maybe try using the hardware layer, but I doubt that will work. I recommend looking into bitmap shaders.