STAMINA mode breaks fragment loading with custom a

2019-09-08 05:22发布

问题:

This code is working as expected on all devices except Sony devices with activated STAMINA mode:

int backStackCount = getSupportFragmentManager().getBackStackEntryCount();    
getFragmentManager()
                .beginTransaction()
                .setCustomAnimations(backStackCount == 0? R.animator.noanim : R.animator.slide_in,
                        R.animator.zoom_out, R.animator.zoom_in, backStackCount == 0? R.animator.noanim : R.animator.slide_out)
                .replace(R.id.container, fragment, String.valueOf(backStackCount))
                .addToBackStack(fragment.getClass().toString())
                .commit();

With STAMINA mode the first Fragment is loaded normally, but the next one does not show up at all (the screen remains black). If I comment out the setCustomAnimations method, the transaction works as expected. What is going on here, how to get the transaction working with activated STAMINA mode?

R.animator.slide_in:

<?xml version="1.0" encoding="utf-8"?>
<set>
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
                    android:interpolator="@android:anim/decelerate_interpolator"
                    android:valueFrom="1.0"
                    android:valueTo="0"
                    android:propertyName="xFraction"
                    android:duration="@android:integer/config_mediumAnimTime" />
</set>

EDIT: solved by myself, see below

回答1:

I used Roman Nurik's method for animating the Fragments. If the STAMINA mode is activated, the animations are disabled and the setXFraction method is called only once with the end value of the animation. The width of the View is 0 at this moment, so it's never going to be placed at the right position.

The solution is to delay the placement until the layout is finished:

public void setXFraction(float xFraction) {
    this.xFraction = xFraction;
    post(() -> {
        final int width = getWidth();
        setX((width > 0) ? (this.xFraction * width) : -9999);
    });
}