与Tab通信的Android Activity:Tab为null

时间:2012-09-07 15:34:06

标签: android tabs android-fragments android-tabs

对于我最新的Android应用程序(API级别15),我使用了新的体系结构,GUI中的每个Tab都由Fragment类表示,该类在PagerAdapter中注册,Tab事件由TabListener处理。

但是,当我想在两个标签之间发送数据时,我遇到了问题。我使用了来自this page的代码示例并编写了以下代码,以便将数据从Tab发送到我的Activity:

@Override
public void onDataReceived(Map<String, List<Map<Integer, String>>> receivedData) {

    Log.i("CarerActivity:onDataReceived", "Map received by Fragment.");
    Log.i("CarerActivity:onDataReceived", receivedData.toString());
    Log.i("Fragment ID", ""+R.id.configurationfragment);

    TabConfiguration configurationFragment = (TabConfiguration) getSupportFragmentManager().findFragmentById(R.id.configurationfragment);

    if(configurationFragment != null){
        Log.i("CarerActivity:onDataReceived", "Fragment not null.");
    }else{
        Log.i("CarerActivity:onDataReceived", "Fragment null!");
    }
}

正确显示receivedData.toString(),因此Tab将其数据发送到Activity。还会显示片段ID。之后输出始终是“CarerActivity:onDataReceived Fragment null!”这使得我无法调用Fragment的任何方法(因为它是null)。

在我的R.java中行

public static final int configurationfragment=0x7f080001;

可以在

下找到
    public static final class id{

任何人都知道我做错了什么或在哪里寻找错误?

设置:Samsung Galaxy Nexus,Android 4.0.3,API等级15,Java 1.6,Mac OS 10.8,Eclipse Juno。

1 个答案:

答案 0 :(得分:1)

这是一篇关于FragmentPagerAdapter

的有趣文章
  

FragmentPagerAdapter将在您滑动时分离每个片段   列表,但将它们保存在内存中,以便它们可以简单地重新附加   当用户滑回时。如果你有更多的碎片,   FragmentStatePagerAdapter值得考虑,因为它将删除   他们,缺点是他们需要作为用户重建   向他们挥手。所以,如果你有更少,更复杂的碎片了   FragmentPagerAdapter很有意义,但考虑一下   FragmentStatePagerAdapter用于更大的集合。

基本上,当您从一个片段滑动到另一个片段时,前一个片段将被销毁(= null)。

解决此问题的一种方法是将新数据保存在第三方课程或您的活动中。然后,当重新创建片段时,将其传递给包含新数据的包。

这是一个例子:

public class PagerUserAdapter extends FragmentStatePagerAdapter
{
    private final static String titles[] = {"Profile", "Badges", "Skills", "Accomplishments"};

    private Bundle args;

    public PagerUserAdapter(FragmentManager fm, CWUser u) 
    {
        super(fm);

        this.args = new Bundle();
        args.putSerializable(Constants.BUNDLE_USER, u);
    }

    public void refresh(CWUser u)
    {
        args.putSerializable(Constants.BUNDLE_USER, u);
        this.notifyDataSetChanged();
    }

    @Override
    public CharSequence getPageTitle(int position)
    {
        return titles[position];
    }

    @Override
    public Fragment getItem(int position) 
    {
        switch(position)
        {
        case 0:
            return ProfileFragment.newInstance(args);
        case 1:
            return BadgesFragment.newInstance(args);
        case 2:
            return SkillsFragment.newInstance(args);
        case 3:
            return AccomplishmentsFragment.newInstance(args);
        default:
            return ProfileFragment.newInstance(args);
        }
    }

    @Override
    public int getCount() 
    {
        return titles.length;
    }

    @Override
    public int getItemPosition(Object object) 
    {
        return POSITION_NONE;
    }
}

public class BadgesFragment extends BaseFragment
{    
    public static BadgesFragment newInstance(Bundle args)
    {
        BadgesFragment f = new BadgesFragment();
        f.setArguments(args);
        return f;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
    {
        super.onActivityCreated(savedInstanceState);

        CWUser u = (CWUser) getArguments().get(Constants.BUNDLE_USER);
            //do what you want with your new data   
    }
}

在获取新数据的活动中,您所要做的就是使用新数据调用适配器的刷新方法。 这就是我如何做到的,它可能有更优雅的解决方案,我对任何建议持开放态度。 该示例基于我的一个开源应用程序,如果您想要挖掘,这里是带有完整代码的project