【问题标题】:How to communicate with fragments when using viewpager?使用viewpager时如何与fragment通信?
【发布时间】:2015-07-19 08:05:12
【问题描述】:

我目前正在使用具有“swipey-tabs”并使用以下 PagerAdapter 的应用程序:

public class TabsPagerAdapter extends FragmentPagerAdapter {

    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
    }


    @Override
    public Fragment getItem(int index) {
        switch (index) {
            case 0:
                return new HomeFragment();
            case 1:
                return new ListFragment();
            case 2:
                return new ChartFragment();
        }

        return null;
    }

    @Override
    public int getCount() {

        return 3;
    }

}

我正在使用以下代码与主要活动中的一个片段进行通信:

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 1)
        {
            if (resultCode == Activity.RESULT_OK)
            {
                String className = data.getExtras().getString("class_name");
                if (className.trim().length() > 0) {
                    HomeFragment homeFrag = (HomeFragment) getSupportFragmentManager().findFragmentById(R.id.home_fragment);
                    if(homeFrag != null) {
                        Log.d("MainActivity", "homeFrag is not null");
                        homeFrag.newClass(className);
                    }else{
                        Log.d("MainActivity", "homeFrag is null");
                        HomeFragment newFragment = new HomeFragment();

                        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                        transaction.replace(R.id.home_fragment, newFragment);
                        transaction.commit();
                        newFragment.newClass(className);
                    }
                    addSubjectToDataBase(className);
                }

            }
        }
    }

我的问题是,当我尝试与主要活动的片段进行通信时,我似乎同时存在多个片段。当我改变屏幕方向或重新启动活动时,我得到了片段的修改版本,但是当我来回滑动查看片段时,我得到片段的旧的、未修改的版本。片段管理器似乎没有注册适配器创建的片段,因为虽然我知道片段已经创建,但片段管理器总是返回一个空主片段。

我应该如何避免这个问题,与主要活动的片段进行通信的最佳方式是什么?

【问题讨论】:

  • 你为什么用OnActivityResult()
  • 我用来更新片段的信息来自用户在按下添加按钮时启动的另一个活动的输入。

标签: android android-fragments android-viewpager


【解决方案1】:

在阅读this post 之后,我为自己的问题找到了解决方案。问题在于,由于FragmentPagerAdapter 管理自己的片段,我试图访问的片段与视图寻呼机使用的片段不同。

我通过修改我的PagerAdapter 来访问视图寻呼机使用的片段标签的方法:

public class TabsPagerAdapter extends FragmentPagerAdapter {

    protected String homeTag;
    protected String listTag;
    protected String chartTag;

    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int index) {
        switch (index) {
            case 0:
                Log.d("Adapter", "returning new homeFragment");
                return new HomeFragment();
            case 1:
                return new ListFragment();
            case 2:
                return new ChartFragment();
        }

        return null;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment createdFragment = (Fragment) super.instantiateItem(container, position);

        switch (position){
            case 0:
                homeTag = createdFragment.getTag();
                break;
            case 1:
                listTag = createdFragment.getTag();
                break;
            case 2:
                chartTag = createdFragment.getTag();
                break;
        }

        return createdFragment;
    }

    public String getHomeTag(){
        return  homeTag;
    }

    public String getListTag(){
        return listTag;
    }

    public String getChartTag(){
        return chartTag;
    }
    @Override
    public int getCount() {

        return 3;
    }

}

然后,在我访问了正确的片段标签之后,修改我的代码以访问正确的片段是一件简单的事情:

HomeFragment homeFrag = (HomeFragment) getSupportFragmentManager().findFragmentByTag(mAdapter.getHomeTag());
                    if(homeFrag != null) {
                        Log.d("MainActivity", "homeFrag is not null");
                        homeFrag.newClass(className);
                    }else{
                        Log.d("MainActivity", "homeFrag is null");
                        HomeFragment newFragment = new HomeFragment();

                        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                        transaction.replace(R.id.pager, newFragment, madapter.get);
                        transaction.commit();
                        newFragment.newClass(className);

【讨论】:

    【解决方案2】:

    这并不优雅,但我会做这样的事情(也许有人会发布更好的解决方案):

    在单例中,我将放置一个片段数组:

    public static Fragment[] sShownFragments = new Fragment[3];
    

    然后在getItem()方法中:

    if(SingletonClass.sShownFragments[index]!=null){
        return mFragments[index];
    }
    
    switch (index) {
            case 0:
                SingletonClass.sShownFragments[index] = new HomeFragment();
                break;
            case 1:
                SingletonClass.sShownFragments[index] = new ListFragment();
            case 2:
                SingletonClass.sShownFragments[index] = new ChartFragment();
            default:
                SingletonClass.sShownFragments[index] = new Fragment();
    }
    return SingletonClass.sShownFragments[index];
    

    然后在getCount(): return SingletonClass.sShownFragments.length();

    现在在您的onActivityResult()

     \\some code ...
     ((HomeFragment)SingletonClass.sShownFragments[0]).newClass(className);
     \\ some other code...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-26
      • 1970-01-01
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多