Android嵌套片段之间的通信

时间:2015-05-26 11:41:16

标签: android android-fragments

我知道当您想要在片段之间进行通信时,您应该通过父活动进行通信。当两个片段在同一级别时,这是有道理的。如果一个嵌套在第二个之内“向上”只是为了返回“向下”是没有意义的。

在这种情况下,模式是有道理的:

   Activity
   ____|____
  /         \
Frag A    Frag B

当一个嵌套在另一个中时,使用该模式没有意义:

   Activity
      |
    Frag A
      |
    Frag B

如果一个嵌套在另一个中,可以直接使用findFragmentByTag(FRAG_X_TAG)进行通信吗?

5 个答案:

答案 0 :(得分:0)

根据API 4.2 documentation,您应该使用getChildFragmentManager()

您可以随时使用BusEvent库,它可以简化组件之间的通信,但您也可能失去代码清晰度。

答案 1 :(得分:0)

这种模式的想法是使用Activity作为Controller接口,FragmentView s - 它们将UI事件发送到{ {1}},然后根据需要更新它们。

这意味着这里真正的问题应该是“片段A是片段B的Controller” - 如果是这样,直接沟通是可以接受的。如果两者都只是“愚蠢的观点”,他们真的不应该彼此了解。

最重要的是,您希望避免制作意大利面条代码,只要您强制执行问题分离,这是可能的。

答案 2 :(得分:0)

听起来你可以使用事件总线。这些是一些最受欢迎的选择:

答案 3 :(得分:0)

另一种选择是使用Google在Google Architecture组件中推广的Model-view-viewmodel(MVVM)结构:

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {
        return selected;
    }
}


public class MasterFragment extends Fragment {
    private SharedViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        model.getSelected().observe(getViewLifecycleOwner(), { item ->
           // Update the UI.
        });
    }
}

更多信息: https://developer.android.com/topic/libraries/architecture/viewmodel#sharing

答案 4 :(得分:-1)

如果你想同时激活超过1个片段......那么使用方法getChildFragmentManager()

例如:

我有一个名为“ShareSpace”的主片段,并有3个子片段.. //在ShareSpace Fragment中

 View view = inflater.inflate(R.layout.fragment_sharespace, container, false);
    mTabletSize = getResources().getBoolean(R.bool.isTablet);
    mContext=getActivity();
    ViewPager pager = (ViewPager) view.findViewById(R.id.pager);

        ShareSpaceAdapter pagerAdapter = new ShareSpaceAdapter(mContext,getChildFragmentManager());
        pager.setAdapter(pagerAdapter);
        mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs_share);
        mSlidingTabLayout.setViewPager(pager);

//在适配器

public ShareSpaceAdapter(Context mContext, FragmentManager fm) {
    super(fm);
    this.mContext = mContext;
    // TODO Auto-generated constructor stub
    try {
        if (home == null) {
            homeFact = FactoryGenerator.getFactory(Constants.HOME);
            home = homeFact.getHomeManagement(Constants.SHARESPACE);
        }
        local = home.readAssets(mContext);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public Fragment getItem(int arg0) {
    Fragment frgmt = null;

    switch (arg0) {
    case 0:

        frgmt = new ShareSpaceFiles(mContext);
        break;
    case 1:

        frgmt=new ShareSpaceFolder(mContext);
        break;
    case 2:

         frgmt = new ShareSpaceInbox(mContext);
         break;

    default:
        break;
    }

    return frgmt;
}

@Override
public int getCount() {
    return PAGE_COUNT;
}

@Override
public CharSequence getPageTitle(int position) {

    switch (position) {
    case 0: // Fragment # 0 - This will show FirstFragment
        return local.getmFiles();//"FILES";
    case 1: // Fragment # 0 - This will show FirstFragment different title
        return local.getmFolders();//"FOLDERS";
    case 2:
        return local.getmMessages();//"MESSAGES";

    default:
        return null;

    }

}

它将同时加载3个子片段