首页 > 解决方案 > Android - Fragments 和 Tabs 通信

问题描述

我对Android很陌生。

这是我的场景:我有一个带有 3 个选项卡的简单应用程序。在每个选项卡中,我想使用一个或多个片段。这是这种情况:

  1. 表 1:
    • 片段 A
  2. 选项卡 2:
    • 片段 B
    • 片段 C
    • 片段 D
  3. 表 3:
    • 片段 E
    • 片段 F

在“Tab 1”中我没有问题。一切都很好。当我需要进入“Tab 2”和“Tab 3”时会出现问题。

在选项卡 2 中,我必须将一些参数从“片段 B”传播到“片段 C”,从“片段 C”传播到“片段 D”。

然后,当用户单击“片段 D”中的某个按钮时,我必须传递到“选项卡 3”,并且必须将一些参数从“片段 D”传播到“片段 E”。

在我的标签处理主要活动中,我使用了这些组件:

我非常简单的FragmentStatePagerAdapter扩展是:

public class MyOwnPageAdapter extends FragmentStatePagerAdapter {
    private int numeroTab;
    public MyOwnPageAdapter(FragmentManager fm, int numeroTab) {
        super(fm);
        this.numeroTab = numeroTab;
    }
    @Override
    public Fragment getItem(int position) {
        switch (position){
            case 0:
                return new FragmentA() ;
            case 1:
                return new FragmentB() ;
            case 2:
                return new FragmentC() ;
            default:
                return null;
        }
    }
    @Override
    public int getCount() {
        return numeroTab;
    }
}

我非常简单的TabLayout.OnTabSelectedListener扩展是:

public class TabSelectedListener implements TabLayout.OnTabSelectedListener {
    private ViewPager viewPager;
    public TabSelectedListener(ViewPager viewPager){

        this.viewPager = viewPager;
    }
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
}

我可以在选项卡 2 中的选项卡内切换片段,我可以从片段 B 切换到片段 C,依此类推。我在片段之间传递参数时遇到问题,尤其是从选项卡 2 中的片段 D 到选项卡 3 中的片段 E

在我的 Fragments 实现中,android.support.v4.app.FragmentManager我可以通过执行以下操作来添加和删除视图(例如片段):

mFragmentManager.beginTransaction().add(rootView.getId(),mListaEdificiFragment, "BUILDS").addToBackStack(null).commit();

问题是参数传播,因为FragmentStatePagerAdapter似乎缓存视图,所以片段构造函数被调用,但onCreate不再onCreateView被调用,所以我无法处理传播的参数。

有什么解决办法吗?还是我的导航模式完全错误?我想避免在一个“大视图”中折叠 Fragment B、Fragment C 和 Fragment D 以隐藏某些部分(对于 Fragment E e Fragment F 相同)

任何建议都更受欢迎

安杰洛

标签: androidandroid-fragmentsandroid-viewpagerandroid-tablayout

解决方案


最后我得到了解决方案。由于主要问题是碎片通信,我遵循了官方文档

假设我有带有文章列表的片段 A 和片段 B 在哪里可以查看所选文章的详细信息,在我的片段 A 中我写道:

public class FragmentA extends Fragment {
    private OnArticleSelectionListener mCallback;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
        }
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.activityedifici, container, false);     
        return rootView;
    }



    public interface OnArticleSelectionListener {

        void onArticleSelection(String articleId);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mCallback = null;
    }


    public void setOnArticleSelectionListener(OnArticleSelectionListener mCallback) {
        this.mCallback = mCallback;
    }
}

如您所见,我声明了以下接口

public interface OnArticleSelectionListener {

        void onArticleSelection(String articleId);
    }

这是文章选择监听器。

在我的主要活动中,我写了以下内容:

public class MainActivity implements FragmentA.OnArticleSelectionListener{
//All my own stuffs

    @Override
    public void onAttachFragment(Fragment fragment) {
        if (fragment instanceof FragmentA){
            FragmentA ef = (FragmentA)fragment;
            ef.setOnArticleSelectionListener(this);
        }
    }
    @Override
    public void onArticleSelection(String articleId) {
        if( getSupportFragmentManager().findFragmentByTag(TAG_ARTICLE_DETAIL) != null ){
        //FragmentB is the article detail and it has already been created and cached
            FragmentB dcf = (FragmentB)getSupportFragmentManager().findFragmentByTag(TAG_ARTICLE_DETAIL);
            dcf.updateArticleDetail( articleId );
        }else{
        //FragmentB is the article detail and it has never been created I create and replace the container with this new fragment
            FragmentB dcf = new FragmentB();
        //Parameter propagation
            Bundle args = new Bundle();
            args.putString(FragmentB.ARG_ARTICLE_ID, articleId);
            dcf.setArguments(args);
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.container_articles, dcf, TAG_ARTICLE_DETAIL);
            transaction.addToBackStack(null);
            transaction.commit();
        }
    }
}

通过这种方式,我能够拦截 FragmentA 中的事件并将它们传播到 FragmentB;当我需要打开一个选项卡时,一切都保持不变,最后(在transaction.commit()或之后dcf.updateArticleDetail( articleId ))我执行以下操作 tabLayout.getTabAt(2).select();,第三个选项卡(选项卡索引从 0 开始)打开并显示详细信息。

我希望这会很有用

安杰洛


推荐阅读