Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update Android fragment from activity?

I want to periodically update a fragment's display based on data I download from the Internet. I have created a Timer and Runnable to periodically retrieve this data as well as a method within the fragment to update it, but I cannot seem to figure out how to gain a reference from the activity to the fragment in order to update it.

I have the following code which was mostly generated by the ADT's Android Project wizard:

    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));
    }   

Here is the code used to create the tabs:

    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;
        }
    }

I have tried using this solution:

How to change fragment's textView's text from activity

But I don't have the fragment ID. Can I create tags? If so, how do I do that in this case? Other SO posts have mentioned Bundles but I am not sending data when creating the fragment; I want to have the fragment periodically updated as data becomes available from the Activity.

like image 883
gonzobrains Avatar asked Mar 30 '14 23:03

gonzobrains


2 Answers

You cannot give your fragments a tag or id but you can create a custom property on your fragment class to mark them.

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;
    }

When can then loop through all the fragments and find the one you need

List<Fragment> allFragments = getSupportFragmentManager().getFragments();
if (allFragments != null) {
    for (Fragment fragment : allFragments) {
        Fragment1 f1 = (Fragment1)fragment;
        if (f1.fragmentType == 1)
            f1.updateFragmentData();
    }
}
}

Add a public method to your fragment that will update the data in your fragment. As you have a reference to it now, you can just call it from your activity.

like image 70
Szymon Avatar answered Oct 20 '22 00:10

Szymon


Here is something you could try:

Since you mention updating the fragment from the activity (with retrieved data), you could do something like this:

In your Runnable or AsyncTask, you can update the adapter with the data retrieved and in your fragment, call the onDatasetChanged() method on the adapter so it will automatically update the view.

If you have multiple fragments, inside those fragments, you could define an interface and then let the activity implement it and then override the method. From within that method in the activity, update the adapter that holds the data. You will have to make the adapter static!

I hope this helps!

like image 34
Eenvincible Avatar answered Oct 20 '22 01:10

Eenvincible