YCStudyWeb
YCStudyWeb copied to clipboard
FlutterFragment&原生Fragment共存问题
我在项目中遇到了一个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");
}
}