如何从Activity更新Android片段?

11
我想定期根据我从互联网下载的数据更新片段的显示。我创建了一个计时器和可运行对象,以周期性地检索此数据,以及一个在片段内更新该数据的方法,但我似乎无法弄清如何从活动获取对片段的引用以便进行更新。
我有以下代码,这主要是由ADT的Android项目向导生成的:
    protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    Log.d(tag, "onCreate()::Entering...");

    setContentView(R.layout.activity_main);

    // Set up the action bar.
    final ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // Create the adapter that will return a fragment for each of the
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(
            getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    // When swiping between different sections, select the corresponding
    // tab. We can also use ActionBar.Tab#select() to do this if we have
    // a reference to the Tab.
    mViewPager
            .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                @Override
                public void onPageSelected(int position) {
                    actionBar.setSelectedNavigationItem(position);
                }
            });

    // For each of the sections in the app, add a tab to the action bar.
    for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) 
    {
        // Create a tab with text corresponding to the page title defined by
        // the adapter. Also specify this Activity object, which implements
        // the TabListener interface, as the callback (listener) for when
        // this tab is selected.
        actionBar.addTab(actionBar.newTab()
                .setText(mSectionsPagerAdapter.getPageTitle(i))
                .setTabListener(this));
    }   

以下是用于创建选项卡的代码:

    public class SectionsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int position) 
    {
        // getItem is called to instantiate the fragment for the given page.

        switch (position)
        {
        case FRAG1_POS:
            return Fragment1.newInstance();

        case FRAG2_POS:
            return Fragment2.newInstance(); 

        default:
            return null;
        }
    }

我尝试使用了这个解决方案:

如何从Activity更改Fragment的TextView文本

但是我没有fragment ID,我能创建标签吗?如果可以,那么在这种情况下我该如何做?其他SO帖子提到了Bundles,但我在创建Fragment时不会发送数据;我希望在数据从Activity变得可用时定期更新Fragment。

2个回答

8
您不能为碎片分配标签或ID,但可以在碎片类上创建自定义属性来标记它们。
switch (position)
    {
    case FRAG1_POS:
        Fragment1 f = Fragment1.newInstance();
        f.fragmentType = 1;
        return f;

    case FRAG2_POS:
        Fragment1 f = Fragment1.newInstance();
        f.fragmentType = 2;
        return f;

    default:
        return null;
    }

当我们可以循环遍历所有片段并找到所需的那个。
List<Fragment> allFragments = getSupportFragmentManager().getFragments();
if (allFragments != null) {
    for (Fragment fragment : allFragments) {
        Fragment1 f1 = (Fragment1)fragment;
        if (f1.fragmentType == 1)
            f1.updateFragmentData();
    }
}
}

在你的片段中添加一个公共方法,用于更新片段中的数据。由于现在你已经有了对它的引用,所以可以直接从你的活动中调用它。

没错,你不能添加标签,但是你可以添加一个充当标签的属性。请查看我的更新。 - Szymon
我之前也考虑过这样做,但是片段不是同一类型的。我需要使用反射吗? - gonzobrains
3
不,这甚至更容易,因为您无需以任何方式标记片段。只需在循环中检查每个片段的类型:if (fragment instanceof YourFragment) - Szymon
不太确定什么是“正常”。也许并不存在这样的事情 :) - Szymon
1
是的,当我说“正常”时,我指的是一些更容易通过文档、现有的谷歌搜索等方式理解的内容。至少现在,如果我的问题得到了赞,它将帮助其他处于类似情况的人! :) - gonzobrains
显示剩余9条评论

2

这里有一些你可以尝试的方法:

因为你提到要从活动中更新片段(使用检索到的数据),所以你可以像这样做:

在你的Runnable或AsyncTask中,你可以用检索到的数据更新适配器,在你的片段中,调用适配器上的onDatasetChanged()方法,它将自动更新视图。

如果你有多个片段,在这些片段内,你可以定义一个接口,然后让活动实现它并重写该方法。在活动的这个方法内,更新包含数据的适配器。你需要使适配器静态!

希望这能帮助到你!


我尝试使用onDatasetChanged(),但没有任何反应。在Fragment类中是否需要重写某个方法来响应此操作?如果不是,那么我需要建立什么样的连接来检索数据和已获取的数据之间的关系。我觉得我漏掉了什么。 - gonzobrains

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