简体   繁体   中英

Update Fragment View within FragmentPagerAdapter in SherlockFragmentActivity

I am following the example FragmentTabsPager under the Samples from ActionBarSherlock .

In my case, I have created a simple SherlockActivity with the TabsPager and the same code from the sample for the FragmentPagerAdapter.

I created two fragments (different classes). The first one contains just four buttons. Depending of which one is clicked, the main Activity gets a code (eg 1,2,3,4). I get correctly the code for the pressed button.

Now, in the second Fragment I want to draw something depending on that code, or what is the same, update dynamically its view.

I have been searched for a solution but I haven´t got anything. In this case I have this:

[MainActivity.java]

      public static class TabsAdapter extends FragmentPagerAdapter
            implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {

private final Context mContext;
        private final TabHost mTabHost;
        private final ViewPager mViewPager;
        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();    
[...]
    @Override
        public Fragment getItem(int position) {
            TabInfo info = mTabs.get(position);
            return Fragment.instantiate(mContext, info.clss.getName(), info.args);

    }

I managed to update the Bundle info.args with the new value, but I don´t know how to pass it to the fragment correctly and order it to update its dynamic View.

Is this possible?

Thanks in advance.

UPDATE

Finally, I used what Sunny kindly explained. I kept an SparseArray with my Fragments so I could definitely access them as I know its position inside MainActivity:

[MainActivity.java]

    //Once the user presses the button on the first fragment, the callback calls
// this function
    public void onImageSelected(int iNumber){

    MySecondFragment msf = (MySecondFragment)mTabsAdapter.getFragment(POS_1);

        if(msf != null){

                msf.setNumImage(iNumber);               
                msf.updateView();                                   
            }                   
       }

And finally in MySecondFragment.java I can access my Layout components (eg a GridView), as they were initialized during onCreateView, so I put all the code I needed inside my updateView() method.

For instance, I update the content of a GridView:

[MySecondFragment.java]

myGridView.setBackground(getResources().getDrawable(iCode));

HTH

UPDATE 2

I have included the following code in order to save the fragments into the state bundle of the main activity. When the application changes from portrait to landscape or viceversa (it is recreated) the function getItem is not being called, so the SparseArray map is not refilled again with the necessary Fragments:

@Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString(CURRENT_TAB, mTabHost.getCurrentTabTag());

        getSupportFragmentManager().putFragment(outState, MyFirstFragment.class.getName(), mTabsAdapter.getFragment(POS_1));

        getSupportFragmentManager().putFragment(outState, MySecondFragment.class.getName(),
                mTabsAdapter.getFragment(POS_2));
    }

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

        if (savedInstanceState != null) {

            MyFirstFragment mff = (MyFirstFragment) getSupportFragmentManager().getFragment(savedInstanceState, MyFirstFragment.class.getName());                           

            if(mff != null)
                mTabsAdapter.setFragment(POS_1, mff);

            MySecondFragment msf = (MySecondFragment) getSupportFragmentManager().getFragment(
                    savedInstanceState, MySecondFragment.class.getName());                          

            if(msf != null)
                mTabsAdapter.setFragment(POS_2, msf);

            mTabHost.setCurrentTabByTag(savedInstanceState
                    .getString(CURRENT_TAB));           
        }
    }

Also, inside the TabsAdapter class:

public Fragment getFragment(int pos) {
    return map.get(pos);
}

public void setFragment (int position, Fragment fragment) {
     map.put(position, fragment);
}

HTH

The source for FragmentPagerAdapter shows that Fragments are given the following tag:

"android:switcher:" + viewId + ":" + id;

Where viewId is the R.id of your ViewPager and id is the page number.

Therefore you can retrieve the second page's Fragment by using:

activity.getSupportFragmentManager().findFragmentByTag(
    "android:switcher:" + pager.getId() + ":2")

Where pager is your ViewPager . You'd then want to cast that returned Fragment to whatever specific class you have, then call a method to pass in the information you need.

anhanniballake answer might work. But This might break in future.

To actually get the fragment you can define a sparesArray in your TabAdapter class

private SparseArray<Fragment> map;

and add your fragments in this array

@Override
public Fragment getItem(int position) {
    TabInfo info = mTabs.get(position);
    Fragment fragment = Fragment.instantiate(mContext, info.clss.getName(), info.args);
    map.put(position, fragment);
    return fragment;
}

You also need to remove the fragment from map when fragment get destroy

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    map.remove(position);
    super.destroyItem(container, position, object);
}

Now define a public method in TabAdapter class which can get Fragments

public Fragment getFragment(int pos) {
    return map.get(pos);
}

Now in Your Main SherlockFragementActivity you can get the instance of any fragment

MyFragment f = (MyFragment) mTabsAdapter.getFragment(1); // 1 means second fragment from left

Now call any method in your fragments using the fragment instance you got above

f.doAnyThingInMySecondFragment();

doAnyThingInMySecondFragment must be declared public :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM