網站首頁 編程語言 正文
場景
Fragment中嵌套Fragment,且被嵌套的Fragment是復用的,點擊其中item后進入詳情,返回后需要回傳數據并刷新列表。
由于是Fragment之間的相互嵌套,不方便使用Intent返回數據,也不方便使用callback回調來返回數據,所以選擇了使用EventBus發送消息,但是發現在列表中使用EventBus發送消息后,Fragment中接收消息的方法會執行多次。
發送消息:
EventBus.getDefault().post(new TestEvent());
接收消息:
@Subscribe(threadMode = ThreadMode.MAIN)
? ? public void onTestEvent(TestEvent event) {
? ? ? ?onSwipeRefresh();
? ? }
也就是onTestEvent方法會被調用多次,數據也會多次刷新。
原因分析
因為Fragment是復用的,而EventBus訂閱消息也在復用的Fragment中,導致該消息被多次訂閱。以ItemFragment為例。
public class ItemFragment extends Fragment {
? ? private static final String ARG_COLUMN_COUNT = "column-count";
? ? private int mColumnCount = 1;
? ? public ItemFragment() {
? ? }
? ? @SuppressWarnings("unused")
? ? public static ItemFragment newInstance(int columnCount) {
? ? ? ? ItemFragment fragment = new ItemFragment();
? ? ? ? Bundle args = new Bundle();
? ? ? ? args.putInt(ARG_COLUMN_COUNT, columnCount);
? ? ? ? fragment.setArguments(args);
? ? ? ? return fragment;
? ? }
? ? @Override
? ? public void onCreate(Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? if (getArguments() != null) {
? ? ? ? ? ? mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
? ? ? ? }
? ? }
? ? @Override
? ? public void onStart() {
? ? ? ? super.onStart();
? ? ? ? // 訂閱消息
? ? ? ? EventBus.getDefault().register(this);
? ? }
? ? @Override
? ? public void onStop() {
? ? ? ? super.onStop();
? ? ? ? // 注銷訂閱
? ? ? ? EventBus.getDefault().unregister(this);
? ? }
}
復用ItemFragment:
public class HomeFragment extends Fragment {
? ? private int activeColor = Color.parseColor("#ffffff");
? ? private int normalColor = Color.parseColor("#666666");
? ? private final String[] tabs = new String[]{"第一頁", "第二頁", "第三頁", "第四頁", "第五頁"};
? ? public View onCreateView(@NonNull LayoutInflater inflater,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ViewGroup container, Bundle savedInstanceState) { ? ? ? ? ? ? ? ? ? ?
? ? ? ? ...
? ? ? ? vp2.setAdapter(new FragmentStateAdapter(getActivity().getSupportFragmentManager(), getLifecycle()) {
? ? ? ? ? ? @NonNull
? ? ? ? ? ? @Override
? ? ? ? ? ? public Fragment createFragment(int position) {
? ? ? ? ? ? ? ? return ItemFragment.newInstance(position + 10);
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public int getItemCount() {
? ? ? ? ? ? ? ? return tabs.length;
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? ...
}
因為創建了5個ItemFragment對象,所以EventBus被訂閱了5次,所以消息時也會被接收5次。
解決方案
1、提前在宿主Activity中進行EventBus消息訂閱,但是該方法不適合多層級的Fragment嵌套,EventBus訂閱不成功,也就接收不到消息。
2、在Fragment中添加標簽,識別當前的Fragment。
@Override
? ? public void onStart() {
? ? ? ? super.onStart();
? ? ? ? // 2 是需要接收消息的Fragment的索引
? ? ? ? if(2 == position) {
? ? ? ? ? ? EventBus.getDefault().register(this);
? ? ? ? }
? ? }
? ? @Override
? ? public void onStop() {
? ? ? ? super.onStop();
? ? ? ? if( 2 == position) {
? ? ? ? ? ? EventBus.getDefault().unregister(this);
? ? ? ? }
? ? }
復用的Fragment中只有索引為2的Fragment才會訂閱消息,所以發送消息的時候只有索引為2的Fragment才能接收到消息,也就解決了多次接收消息的問題。
3、消息中添加標記。
@Subscribe(threadMode = ThreadMode.MAIN)
? ? public void onTestEvent(TestEvent event) {
? ? ? ? if (event != null) {
? ? ? ? ? ? // 2 是需要接收消息的Fragment的索引
? ? ? ? ? ? if(event.getPosition() == 2){
? ? ? ? ? ? ? ? onSwipeRefresh();
? ? ? ? ? ? }
? ? ? ? }
? ? }
EventBus在post消息的時候,把需要哪一個頁面刷新的position發送,接收消息時識別根據索引判斷需要哪一個頁面刷新。不一定要Fragment的position,只要能唯一識別Fragment就行。
原文鏈接:https://blog.csdn.net/qq_34202054/article/details/123531499
相關推薦
- 2023-07-30 el-table自定義合并行或列
- 2022-07-13 求兩個降序單鏈表的并集(利用原有鏈點)
- 2023-10-11 MP、MybatisPlus、聯表查詢、自定義sql、Constants.WRAPPER、ew (二
- 2022-04-05 Pandas的DataFrame如何做交集,并集,差集與對稱差集_python
- 2022-10-01 終于搞懂了Python中super(XXXX,?self).__init__()的作用了_pytho
- 2023-03-16 Android藍牙服務查找附近設備分析探索_Android
- 2023-12-21 Redis HyperLogLog的使用
- 2021-12-19 詳細易懂注解,二維數組楊輝三角的實現,算法入門
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支