0

对于我最新的 Android 应用程序(API 级别 15),我使用了新架构,其中 GUI 中的每个选项卡都由在 PagerAdapter 注册的 Fragment 类表示,并且 Tab 事件由 TabListener 处理。

但是,当我想在两个选项卡之间发送数据时,我遇到了问题。我使用此页面中的代码示例并编写了以下代码以将数据从选项卡发送到我的活动:

@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 的任何方法(因为它为空)。

在我的 R.java 中

public static final int configurationfragment=0x7f080001;

可以在下面找到

    public static final class id{

.

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

设置:三星 Galaxy Nexus,Android 4.0.3,API 级别 15,Java 1.6,Mac OS 10.8,Eclipse Juno。

4

1 回答 1

1

这是一篇关于FragmentPagerAdapter的有趣文章

当您在列表中滑动时,FragmentPagerAdapter 将分离每个片段,但将它们保存在内存中,以便在用户向后滑动时可以简单地重新连接它们。如果您有大量的 Fragment,则值得考虑使用 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   
    }
}

在您的活动中,当您获取新数据时,您所要做的就是使用新数据调用适配器的刷新方法。我就是这样做的,它可能有更优雅的解决方案,我愿意接受任何建议。该示例基于我的一个开源应用程序,如果您想挖掘,这里是包含完整代码的项目。

于 2012-09-07T15:42:07.083 回答