YCStudyWeb icon indicating copy to clipboard operation
YCStudyWeb copied to clipboard

FlutterFragment&原生Fragment共存问题

Open Iridescentangle opened this issue 4 years ago • 0 comments

我在项目中遇到了一个FlutterFragment和原生Fragment共存的问题。

项目主页采用BottomNavigationView+Fragment的结构,切换底部导航时使用FragmentManager.hide隐藏其他fragment,show展示当前fragment的逻辑,例如:

[FragmentA , FragmentB , FragmentC]

[index0 , index1 , index2 ]

FragmentA继承自FlutterFragment;

FragmentBC为原生Fragment;

遇到的问题:默认展示B,切换到A,待Flutter页面加载完成,再切换回B,然后跳转到新Activity后返回当前页面。

理论上应该还是展示B,但此时展示的为A.

但当我将调用的api改为FragmentManager.replace之后,这个现象就消失了.

public class FlutterFragmentCachedActivity extends AppCompatActivity {

    private FrameLayout rlFlutter;
    private FlutterFragment flutterFragment;
    private Fragment nativeFragment;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flutter_fragment);
        rlFlutter = findViewById(R.id.rl_flutter);
        addFlutterView();
        initView();
    }

    private void initView() {
        showFragment(0);
    }
    public void showNative(View view){
        showFragment(0);
    }
    public void showFlutter(View view){
        showFragment(1);
    }
    public void jump(View view){
        Intent intent = new Intent(this,DemoActivity.class);
        startActivity(intent);
    }

    private void showFragment(int index){
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
//        if(flutterFragment != null){
//            transaction.hide(flutterFragment);
//        }
//        if(nativeFragment != null){
//            transaction.hide(nativeFragment);
//        }
        switch (index){
            case 0:
                nativeFragment = getSupportFragmentManager().findFragmentByTag("native");
                if(nativeFragment == null){
                    nativeFragment = new DemoFragment();
                }
//                if(!nativeFragment.isAdded()){
//                    transaction.add(R.id.rl_flutter,nativeFragment,"native");
//                }
                transaction.replace(R.id.rl_flutter,nativeFragment);
                break;
            case 1:
                flutterFragment = (FlutterFragment) getSupportFragmentManager().findFragmentByTag("flutter");
                if(flutterFragment == null){
                    flutterFragment = FlutterFragment.withCachedEngine("my_engine_id").build();
                }
//                if(!flutterFragment.isAdded()){
//                    transaction.add(R.id.rl_flutter,flutterFragment,"flutter");
//                }
                transaction.replace(R.id.rl_flutter,flutterFragment);
                break;
            default:
                break;
        }
        transaction.commitAllowingStateLoss();
    }


    private void addFlutterView() {
        // 通过FlutterFragment引入Flutter编写的页面
        // 通过FlutterFragment.createDefault()创建出FlutterFragment
        // 需要注意这里的FlutterFragment位于io.flutter.embedding.android包中
        //FlutterFragment flutterFragment = FlutterFragment.createDefault();

        // 创建可缓存的FlutterEngine对象
        FlutterEngine flutterEngine = new FlutterEngine(this);
        flutterEngine.getNavigationChannel().setInitialRoute("yc");
        flutterEngine.getDartExecutor().executeDartEntrypoint(
                DartExecutor.DartEntrypoint.createDefault()
        );
        // todo 放在这里不生效,思考为什么
        // flutterEngine.getNavigationChannel().setInitialRoute("yc");
        // 将FlutterEngine缓存起来,这里传入的"my_engine_id"就相当于缓存名称。
        FlutterEngineCache.getInstance().put("my_engine_id", flutterEngine);

        // 通过FlutterFragment引入Flutter编写的页面
        // 过FlutterFragment.withCachedEngine()方法来创建FlutterFragment,参数传入上面的缓存名称。
        // 需要注意,withCachedEngine()方法返回的是一个CachedEngineFragmentBuilder对象,
        // 同样是使用了建造者模式,但是它是没有initialRoute()方法的,如果我们要指定初始路由,
        // 需要在创建FlutterEngine对象时通过setInitialRoute()方法来设置。
//        FlutterFragment flutterFragment = FlutterFragment.withCachedEngine("my_engine_id").build();
//
//        //放在这里不生效,思考为什么
//        //flutterEngine.getNavigationChannel().setInitialRoute("yc");
//
//        getSupportFragmentManager()
//                .beginTransaction()
//                .add(R.id.rl_flutter, flutterFragment)
//                .commit();

        //放在这里不生效,思考为什么
        // todo flutterEngine.getNavigationChannel().setInitialRoute("yc");
    }


}

Iridescentangle avatar Dec 23 '21 09:12 Iridescentangle