Android Xamarin:FragmentManager.FindFragmentByTag返回null的时机问题
为什么Commit后立刻找不到Fragment?怎么解决?
这个问题我之前做Xamarin Android开发时也踩过坑,核心原因是Fragment事务的Commit()方法是异步执行的!
当你调用Commit()时,系统只是把这个事务加入到主线程的消息队列中,并不会立刻执行Fragment的添加操作。所以你在Commit之后马上调用FindFragmentByTag,此时事务还没被执行,自然返回null。
下面给你几个可行的解决办法:
1. 改用同步提交的CommitNow()
如果你的场景允许同步执行事务,可以把Commit()换成CommitNow(),它会立即执行事务,完成后就能直接通过标签找到Fragment:
var fragmentTag = typeof(MyFragment).Name; myFragment = new MyFragment(); FragmentManager.BeginTransaction() .Add(Resource.Id.FrameLayout, myFragment, fragmentTag) .CommitNow(); // 替换成CommitNow // 现在这里就能找到Fragment了 var foundFragment = FragmentManager.FindFragmentByTag<MyFragment>(fragmentTag);
⚠️ 注意:CommitNow()不能在Activity.OnSaveInstanceState()之后调用,否则会抛出异常,适合在Activity初始化(比如OnCreate)这类场景使用。
2. 延迟到事务执行完成后再查找
如果必须用异步的Commit(),可以通过主线程Handler的Post()方法,把查找操作放到消息队列的后面,等事务执行完再执行:
var fragmentTag = typeof(MyFragment).Name; myFragment = new MyFragment(); FragmentManager.BeginTransaction() .Add(Resource.Id.FrameLayout, myFragment, fragmentTag) .Commit(); // 用Handler.Post延迟执行查找 new Handler(Looper.MainLooper).Post(() => { var foundFragment = FragmentManager.FindFragmentByTag<MyFragment>(fragmentTag); // 这里处理找到的Fragment });
另外,也可以给事务添加完成监听器(AndroidX支持):
var transaction = FragmentManager.BeginTransaction() .Add(Resource.Id.FrameLayout, myFragment, fragmentTag); transaction.AddOnCompleteListener(() => { var foundFragment = FragmentManager.FindFragmentByTag<MyFragment>(fragmentTag); // 事务完成后执行操作 }); transaction.Commit();
3. 在Fragment生命周期回调中处理
你也可以在MyFragment的生命周期方法里(比如OnViewCreated或OnResume),通过FragmentManager查找自身或者其他Fragment,此时Fragment已经被成功添加到Manager中了:
public class MyFragment : Fragment { public override void OnViewCreated(View view, Bundle savedInstanceState) { base.OnViewCreated(view, savedInstanceState); // 这里可以通过标签找到自己 var self = FragmentManager.FindFragmentByTag<MyFragment>(typeof(MyFragment).Name); } }
最后再确认下你的标签是否正确:typeof(MyFragment).Name是没问题的,只要你添加事务时用的标签和查找时一致就不会有问题。
内容的提问来源于stack exchange,提问作者Aiko West
相关产品推荐
相关产品推荐

