简体   繁体   中英

flutter reuse fragment float above other views

I have two reuse fragments, and the second on is a flutter fragment, which behave strange.

above Android API 29, flutter fragment will render above first fragment after the detail activity pop out of stack.

under Android API 29, flutter fragment always render above all views in the main activity.

I create this repository to reproduce this error.

This unsolved question is similar to mine.

this code shows how I reuse fragments

    private void switchTo(String tag) {

        FragmentManager supportFragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
        if (tag.equals("home")) {
            fragmentTransaction.show(homeFragment);
            fragmentTransaction.hide(notificationsFragment);
        } else {
            fragmentTransaction.show(notificationsFragment);
            fragmentTransaction.hide(homeFragment);
        }
        fragmentTransaction.commitNowAllowingStateLoss();
    }

this is where flutter fragment add to the view

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        FragmentManager fragmentManager = getChildFragmentManager();
        if (mRepGoalsFlutterFragment1 == null) {
            mRepGoalsFlutterFragment1 = FlutterFragment.withNewEngine()
                    .build();
            fragmentManager
                    .beginTransaction()
                    .add(R.id.card_view7,
                            mRepGoalsFlutterFragment1,
                            TAG_REP_GOALS_FLUTTER_FRAGMENT_1)
                    .commit();
        }

        return inflater.inflate(R.layout.fragment_notifications, container, false);
    }

In my Fragment, I have to detachFlutterEngine myself to fix this problem.

private FlutterView myFlutterView;
private boolean isFlutterHidden = false;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = super.onCreateView(inflater, container, savedInstanceState);
    myFlutterView = FlutterBoostUtils.findFlutterView(view);
    return view;
}

@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    isFlutterHidden = hidden;
    updateFlutterViewHidden();
}

@SuppressLint("VisibleForTests")
void updateFlutterViewHidden() {
    if (myFlutterView == null) return;
    if (isFlutterHidden) {
        myFlutterView.setVisibility(View.GONE);
    } else {
        myFlutterView.setVisibility(View.VISIBLE);
    }
}

@Override
public void onResume() {
    super.onResume();
    updateFlutterViewHidden();
}

Combine your posts with Github issue( https://github.com/flutter/flutter/issues/59968 ),the solution is create self class extends FlutterFragment, get flutterSurfaceView in the onFlutterSurfaceViewCreated .

    private FlutterSurfaceView flutterView;
    @Override
    public void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfaceView) {
        super.onFlutterSurfaceViewCreated(flutterSurfaceView);
        LogUtils.d(TAG, "onFlutterSurfaceViewCreated开始");
        this.flutterView = flutterSurfaceView;
        LogUtils.d(TAG, "onFlutterSurfaceViewCreated结束");
    }

Then setVisibility in onResume.

@SuppressLint("解决FlutterFragment切换到前台显示的问题")
void updateFlutterViewVisibility() {
    if (flutterView == null) {
        return;
    }
    if (isFlutterHidden) {
        flutterView.setVisibility(View.GONE);
    } else {
        flutterView.setVisibility(View.VISIBLE);
    }
}

@Override
public void onResume() {
    LogUtils.d(TAG, "onResume开始");
    super.onResume();
    updateFlutterViewVisibility();
    LogUtils.d(TAG, "onResume结束");
}

@Override
public void onHiddenChanged(boolean hidden) {
    LogUtils.d(TAG, "onHiddenChanged开始");
    super.onHiddenChanged(hidden);
    isFlutterHidden = hidden;
    updateFlutterViewVisibility();
    LogUtils.d(TAG, "onHiddenChanged结束");
}

Create your self class extends FlutterFragment like this:

FlutterFragment.CachedEngineFragmentBuilder(
        YourFlutterFragment::class.java,
        YourFlutterFragmentEngineId
    )
        .shouldAttachEngineToActivity(false)
        .build<YourFlutterFragment>()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM