Communication Fragment - Activity dans le cadre d'un FragmentPagerAdapter
Bonjour,
Pour illustrer un problème que j'ai avec l'utilisation d'un FragmentPagerAdapter, voici une appli basique.
Elle utilise un seul onglet. Le fragment de cet onglet utilise une interface renseignée lors d'un onAttach() pour communiquer avec son activity. L'activity utilise un getItem() du FragmentPagerAdapter pour communiquer avec le fragment actif.
Voici la procédure : je clique sur le menu "Settings", l'activity appelle une fonction du fragment, qui appelle elle-même une fonction de l'activity.
Cela fonctionne sans aucun problème jusqu'à ce que l'on change de format d'affichage (on tourne l'appareil). Là j'ai l'impression que lorsque l'on reconstruit l'activity, on reconstruit bien un nouveau fragment, mais que l'ancien reste toujours actif... Et lorsque le fragment appelle l'activity, on utilise un pointeur null pour l'interface renseignée lors d'un onAttach()...
J'aimerai comprendre pourquoi cela se passe ainsi pour avancer dans mes connaissances. De même, la mémorisation des fragments dans mon FragmentPagerAdapter n'est peut-être pas la meilleure solution. Il faudrait mieux rechercher le bon fragment par son nom ou id, mais comment faire ?
Je vous remercie par avance pour votre aide, et veuillez me pardonner si ce sujet à déjà été traité...
Voici le code pour l'activity :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
public class MainActivity extends Activity implements ActionBar.TabListener,
MainListGeneralFragment.mainListener
{
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
{
@Override
public void onPageSelected(int position)
{
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++)
{
actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
final MainListGeneralFragment fragCurrentFragment =
(MainListGeneralFragment) mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
fragCurrentFragment.onTest();
return true;//super.onOptionsItemSelected(item);
}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction)
{
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction)
{
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction)
{
}
private class SectionsPagerAdapter extends FragmentPagerAdapter
{
private Fragment[] priv_fragListPages;
public SectionsPagerAdapter(FragmentManager fm)
{
super(fm);
priv_fragListPages = new Fragment[1];
priv_fragListPages[0] = null;
}
@Override
public Fragment getItem(int intPosition)
{
if (priv_fragListPages[intPosition] == null)
{
Fragment fNewFragment;
fNewFragment = MainListGeneralFragment.newInstance();
priv_fragListPages[intPosition] = fNewFragment;
}
return priv_fragListPages[intPosition];
}
@Override
public int getCount()
{
return 1;
}
@Override
public CharSequence getPageTitle(int position)
{
return "Test";
}
}
public String getTextToShow()
{
return "A que coucou !!!";
}
} |
Pour le fragment :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
public class MainListGeneralFragment extends Fragment
{
public interface mainListener
{
public String getTextToShow();
}
private mainListener priv_mlListener;
public static MainListGeneralFragment newInstance()
{
MainListGeneralFragment fragment = new MainListGeneralFragment();
return fragment;
}
public MainListGeneralFragment()
{
}
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
try
{
priv_mlListener = (mainListener) activity;
}
catch (ClassCastException e)
{
throw new ClassCastException(activity.toString() + " must implement mainListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_my, container, false);
}
public void onTest()
{
priv_mlListener.getTextToShow();
}
} |
PS : Une coquille était resté dans le code de l'activity. J'ai retiré la ligne...