Fresco: Android N with Fragment bug

Created on 26 Jul 2017  ·  15Comments  ·  Source: facebook/fresco

Hi;
device:google pixel Android 7.1 and hauwei mate9 Android 7.0
Fresco is not visible on Android N devices, using the fragment jump, Android N below is ok.

Tested the other library is ok .

initialization,one/two:fresco , Three four:Glide
init

start fragment:
load

bug

All 15 comments

Hi @hcadoid, thanks for raising this issue. What do you mean by "fragment jump"? Is this a particular fragment transition?

Also which Fresco library are you using? Would be great if you can provide some small code sample that reproduces the issue.

yes,I use fresco and Glide to compare. "fragment jump" is fargment Transaction.
Here's my code:
FrescoActivity
public class FrescoActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fresco);
if (savedInstanceState == null) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        transaction.setCustomAnimations(
                R.anim.h_fragment_enter,
                R.anim.h_fragment_exit,
                R.anim.h_fragment_pop_enter,
                R.anim.h_fragment_pop_exit
        );
        transaction.replace(R.id.fl_container, FrescoMainFragment.newInstance());
        transaction.commit();
    }
}

}

FrescoMainFragment
public class FrescoMainFragment extends Fragment {

private SimpleDraweeView s1,s2,s3,s4;

public static FrescoMainFragment newInstance() {

    Bundle args = new Bundle();
    FrescoMainFragment fragment = new FrescoMainFragment();
    fragment.setArguments(args);
    return fragment;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View mView =inflater.inflate(R.layout.fragment_fresco, container, false);
    initView(mView);
    return mView;
}

private void initView(View mView) {
    s1= (SimpleDraweeView) mView.findViewById(R.id.s1);
    s2= (SimpleDraweeView) mView.findViewById(R.id.s2);
    s3= (SimpleDraweeView) mView.findViewById(R.id.s3);
    s4= (SimpleDraweeView) mView.findViewById(R.id.s4);
    s1.setImageURI("http://odqp9ta7o.qnssl.com/5454114758854668288");
    s2.setImageURI("http://odqp9ta7o.qnssl.com/5464149113932808192");
    Glide.with(this).load("http://odqp9ta7o.qnssl.com/5429034688435023872").into(s3);
    Glide.with(this).load("http://odqp9ta7o.qnssl.com/5468585586862010368").into(s4);

    Button btn= (Button) mView.findViewById(R.id.btn);

    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final FragmentTransaction transaction =  getFragmentManager().beginTransaction();
            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            transaction.setCustomAnimations(
                    R.anim.h_fragment_enter,
                    R.anim.h_fragment_exit,
                    R.anim.h_fragment_pop_enter,
                    R.anim.h_fragment_pop_exit
            );

            transaction.addToBackStack(null);

            transaction.hide(FrescoMainFragment.this);
            transaction.add(R.id.fl_container, OtherFragment.newInstance());
            transaction.commit();
        }
    });

}

OtherFragment
public class OtherFragment extends Fragment {

public static OtherFragment newInstance() {

    Bundle args = new Bundle();

    OtherFragment fragment = new OtherFragment();
    fragment.setArguments(args);
    return fragment;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.test_linearlayout, container, false);
}

}
I think it might be this code:transaction.hide (FrescoMainFragment.this);

Android N changed visibility handling for Drawables. I've added a workaround, see #1445:

impleDraweeView.setLegacyVisibilityHandlingEnabled(true)

@oprisnik This does not work。

s1= (SimpleDraweeView) mView.findViewById(R.id.s1);
s2= (SimpleDraweeView) mView.findViewById(R.id.s2);
s3= (SimpleDraweeView) mView.findViewById(R.id.s3);
s4= (SimpleDraweeView) mView.findViewById(R.id.s4);
s1.setLegacyVisibilityHandlingEnabled(true);
s2.setLegacyVisibilityHandlingEnabled(true);
s1.setImageURI("http://odqp9ta7o.qnssl.com/5454114758854668288");
s2.setImageURI("http://odqp9ta7o.qnssl.com/5464149113932808192");

Glide.with(this).load("http://odqp9ta7o.qnssl.com/5429034688435023872").into(s3); Glide.with(this).load("http://odqp9ta7o.qnssl.com/5468585586862010368").into(s4);

Does not work setLegacyVisibilityHandlingEnabled on Android N galaxy s8+, fresco 1.5

I confirm that setLegacyVisibilityHandlingEnabled doesn't work on Android N Sony Xepria Z5, fresco 1.5.

I already created a sample project to reproduce this problem. Please take a look at it. Thanks!
https://github.com/hnvn/frescobugdemo

@oprisnik can you fix this problem soon?

I don't think I'll have time for a proper fix soon. However, doing something along the lines of

setExitSharedElementCallback(new SharedElementCallback() {
    @Override
    public void onSharedElementEnd(List<String> names,
                                   List<View> elements,
                                   List<View> snapshots) {
        super.onSharedElementEnd(names, elements, snapshots);
        for (final View view : elements) {
            if (view instanceof SimpleDraweeView) {
                view.post(() -> {
                    view.setVisibility(View.VISIBLE);
                    view.requestLayout();
                });
            }
        }
    }
});

as mentioned in #1445 should work.

The problem is that Google changed the visibility API and I didn't find an easy way to fix that for Drawee.

Pull requests are welcome :)

Thanks for your suggestion. But I am still in the dark, where shall I place this code?

@hnvn take a look at the comments in #1445. You have to do this in your activity / fragment

I don't know why, but if I replace hide() and add() by replace() fragment, the problem has gone.

Same here. I want to achieve animation in transaction with hide and show fragments. All images disappear during animation.

This is an issue with setLegacyVisibilityHandlingEnabled, so a duplicate of #1445.

Was this page helpful?
0 / 5 - 0 ratings