Reputation:
I know there are already some questions to this problem. But I am really new in Android and ecspecially to Fragments
and Viewpager
. Pls have passion with me. I didn't found a answer which fits to my code.
I dont know how to refresh a fragment or reload it when it's "active" again.
TabsPagerAdapter.java:
public class TabsPagerAdapter extends FragmentPagerAdapter{
public TabsPagerAdapter(FragmentManager fm){
super(fm);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new KFZFragment();
case 1:
return new LogFragment();
case 2:
return new TrackFragment();
}
return null;
}
@Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
I have this 3 Fragments (KFZFragment,LogFragment,TrackFragment
) and on the TrackFragment
I calculate some data and this data should be display in a ListView in LogFragment
.
But when I change to LogFragment it's not the latest data. So it doesnt refresh.
Now how should I modify my code to refresh the fragments when it's "active"?
MainActivityFragment.java:
public class MainActivityFragment extends FragmentActivity implements ActionBar.TabListener{
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
List<Fragment> fragments;
private String[] tabs = { "KFZ", "Fahrten Log", "Kosten Track" };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_fragment);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this, KFZFragment.class.getName(),savedInstanceState));
fragments.add(Fragment.instantiate(this, LogFragment.class.getName(),savedInstanceState));
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
}
return super.onKeyDown(keyCode, event);
}
}
Pls help me out.
Upvotes: 2
Views: 15687
Reputation: 7108
I agree with Jonathan Lin
But if the fragment you want to update is the fragment that is currently shown you can do something similar to this:
public class DisplayPagerAdapter extends FragmentPagerAdapter {
private static final String TAG = "DisplayPagerAdapter";
SparseArray<DisplayFragment> registeredFragments = new SparseArray<DisplayFragment>();
public DisplayPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
DisplayCoreModule display = DisplayCoreModule.getInstance();
return (display != null && display.getPagesCount() > 0) ? display.getPagesCount() : 1;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public Fragment getItem(int position) {
Log.d(TAG, "getItem " + position);
return DisplayFragment.newInstance(position);
}
@Override
public CharSequence getPageTitle(int position) {
DisplayCoreModule display = DisplayCoreModule.getInstance();
if (display != null && display.getPagesCount() > 0) {
return "Side " + (position+1);
} else {
return super.getPageTitle(position);
}
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Log.d(TAG, "instantiateItem " + position);
DisplayFragment fragment = (DisplayFragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
Log.d(TAG, "destroyItem " + position);
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
public SparseArray<DisplayFragment> getRegisteredFragments() {
return registeredFragments;
}
}
It is the registeredFragments part that I wanted to show you.
Since you use FragmentPagerAdapter then getRegisteredFragment(int position) will always return one of your fragments given that you provide a valid position. Should you change to FragmentStatePagerAdapter at some point, it can return null on some of the positions.
Now, in TrackFragment create a callback to your MainActivity, which then informs LogFragment, shown here in pseudo code:
Fragment TrackFragment {
interface TrackFragmentCallback() {
public void newInfo()
}
TrackFragmentCallback trackFragmentCallback;
onAttatch() {
// make sure to implement TrackFragmentCallback on MainActivity
trackFragmentCallback = (TrackFragmentCallback)getActivity();
}
// When this fragment has new info, simply do:
trackFragmentCallback.newInfo();
}
MainActivity implements TrackFragmentCallback {
newInfo() {
// get LogFragment
LogFragment logFragment = pagerAdapter.getRegisteredFragment(1);
if (logFragment != null) {
logFragment.update();
}
}
}
Hope this helps.
Upvotes: 0
Reputation: 20744
In each of your KFZFragment
, LogFragment
, and TrackFragment
, you should be able to override onResume
in your fragment class and put your necessary refresh/reload code there.
Upvotes: 2