FragmentTabHost和Fragments - 如何在选项卡之间传递数据?

5

我有一个MainActivity(FragmentActivity),其中包含一个FragmentTabHost。

public class FragmentTabs extends FragmentActivity {
    private FragmentTabHost mTabHost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.fragment_tabs);
        mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

        mTabHost.addTab(mTabHost.newTabSpec("classA").setIndicator("Class A"),
            ClassA.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("classB").setIndicator("Class B"),
            ClassB.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("classC").setIndicator("Class C"),
            ClassC.class, null);
    }
}

ClassA、ClassB和ClassC都是Fragments(android.support.v4.app.Fragment)。

我需要在这些Fragments之间传递数据(并调用方法)。我该如何获取每个Fragment的引用,像这样:

ClassA mClassAFragment = ???;

我已经尝试使用getSupportFragmentManager().findFragmentByTag()方法,并且还尝试了探索mTabHost的能力。但是都无法获得它们。

你可以提供一种解决方法或者提出另一种可行的方式吗?

3个回答

11

楼主在这里。为了解决这个问题,我已经重载了FragmentActivity中的onAttachFragment方法:

public class FragmentTabs extends FragmentActivity {
    private FragmentTabHost mTabHost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
    }

    @Override
    public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);

    if (fragment.getClass() == ClassA.class) {
        ClassA mClassAFragment = (ClassA)fragment
            ...
        }
    }
}

很棒的建议。我认为这是一个相当不错的方法去做。 - Siggy
1
我认为你应该对片段类进行.equals()比较,而不是直接使用==比较器。 - alexgophermix
2
或者使用 instanceof 更好:'fragment instanceof ClassA' - kgautron
它只会调用一次,我希望如此。 - Ajit Kumar Dubey
请解释一下你是如何解决这个问题的。我正在使用,但它在附加片段后第一次调用,之后再也没有被调用过。 - Ajit Kumar Dubey

3
您可以像这样获取您的片段:
YourFragment frag = (YourFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.fragmentid));

要向片段发送数据,您可以采用以下方法,创建一个新的事务并通过捆绑包发送数据。

Bundle arguments = new Bundle();
arguments.putString("some id string", "your data");
YourFragment fragment = new YourFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction().add(R.id.fragmentid, fragment).commit();

8
还不错。不幸的是,findFragmentById() 与 FragmentTabHost 不兼容,因为 fragment 只有在被选中为当前标签页时才会被创建。也就是说,ClassB 和 ClassC 直到我选择它们时才会存在。我会将你的回复标记为答案,因为我认为它非常接近并且非常有帮助。我会提供我的答案以获取更多信息。 - Rowan Freeman

2

这可以通过 android.support.v4.app.FragmentTabHost.addTab(TabSpec, Class, Bundle args) 的第三个参数来实现, 然后可以通过 android.support.v4.app.Fragment.getArguments() 来检索 args。

public class Tab1Fragment extends BaseFragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // do something with the arguments
    Log.i("DEBUG", "" + getArguments());
    // ...
}

}


很遗憾,不行。这显然是最初的意图,但getArguments()总是返回null。真是可惜... - Gábor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接