Reputation: 2239
I am having some difficulty correctly using and managing fragments in my project.
I am starting with this Android Developers project as a basis.
The mainactivity extends SampleActivityBase and starts a simple fragment:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
SlidingTabsBasicFragment fragment = new SlidingTabsBasicFragment();
transaction.replace(R.id.sample_content_fragment, fragment);
transaction.commit();
}
The SlidingTabsbasicFragment class extends Fragment and returns a layout onCreateView:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_sample, container, false);
}
Then in another class that extends PagerAdapter, the content of the view based on the position is altered:
@Override
public Object instantiateItem(ViewGroup container, int position) {
// Inflate a new layout from our resources
View view = getActivity().getLayoutInflater().inflate(R.layout.pager_item,
container, false);
// Add the newly created View to the ViewPager
container.addView(view);
// Retrieve a TextView from the inflated View, and update it's text
TextView title = (TextView) view.findViewById(R.id.item_title);
title.setText(String.valueOf(position + 1));
Log.i(LOG_TAG, "instantiateItem() [position: " + position + "]");
// Return the View
return view;
}
This gives me the basic tab functionality that I am looking for. I have even change the layout by inflating a new one based on the position okay. But now I am attempting to implemented a custom calendar called Caldroid.
The main class here extends FragmentActivity. This allows it to setContentView and use FragmentTransaction and .replace to change a layout with an ID into a fragment with the custom calendar on it:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy");
// Setup caldroid fragment
// **** If you want normal CaldroidFragment, use below line ****
caldroidFragment = new CaldroidFragment();
// //////////////////////////////////////////////////////////////////////
// **** This is to show customized fragment. If you want customized
// version, uncomment below line ****
// caldroidFragment = new CaldroidSampleCustomFragment();
// Setup arguments
// If Activity is created after rotation
if (savedInstanceState != null) {
caldroidFragment.restoreStatesFromKey(savedInstanceState,
"CALDROID_SAVED_STATE");
}
// If activity is created from fresh
else {
Bundle args = new Bundle();
Calendar cal = Calendar.getInstance();
args.putInt(CaldroidFragment.MONTH, cal.get(Calendar.MONTH) + 1);
args.putInt(CaldroidFragment.YEAR, cal.get(Calendar.YEAR));
args.putBoolean(CaldroidFragment.ENABLE_SWIPE, true);
args.putBoolean(CaldroidFragment.SIX_WEEKS_IN_CALENDAR, true);
// Uncomment this to customize startDayOfWeek
// args.putInt(CaldroidFragment.START_DAY_OF_WEEK,
// CaldroidFragment.TUESDAY); // Tuesday
caldroidFragment.setArguments(args);
}
setCustomResourceForDates();
// Attach to the activity
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.calendar1, caldroidFragment);
t.commit();
What I am trying to achieve is retaining my tabbed layout, and generating the custom calendar inside only one of the tabs. I'd appreciate any direction / help / resources or alternative suggestions.
I've included some code snippets, but both projects exist (more or less) as originals:
Thanks for any help anyone can provide.
*(1) Added PagerAdapter as requested: (From what I've seen, people say not to mess around with instantiateItem?)
class SamplePagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return 3;
}
@Override
public boolean isViewFromObject(View view, Object o) {
return o == view;
}
@Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0:
return "Item 1";
case 1:
return "Item 2";
case 2:
return "Item 3";
}
return "Item " + (position + 1);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// Inflate a new layout from our resources
View view = null;
if(position==2) {
view = getActivity().getLayoutInflater().inflate(R.layout.item_1, container, false);
container.addView(view);
} else if(position==0) {
view = getActivity().getLayoutInflater().inflate(R.layout.item_2, container, false);
container.addView(view);
} else {
view = getActivity().getLayoutInflater().inflate(R.layout.item3, container, false);
container.addView(view);
}
Log.i(LOG_TAG, "instantiateItem() [position: " + position + "]");
// Return the View
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
Log.i(LOG_TAG, "destroyItem() [position: " + position + "]");
}
}
Upvotes: 0
Views: 555
Reputation: 49837
What you need to do is use a FragmentStatePagerAdapter
instead of PagerAdapter
. You essentially only need to define how many Tabs
you have and which Fragment
belongs in each Tab
:
private class ExampleAdapter extends FragmentStatePagerAdapter {
public ExampleAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// Return the correct Fragment for each Tab
// The position corresponds to the position of the Tab
// So the first Tab has a position of 0, the second Tab has a position of 1...
switch (position) {
case 0:
return new Fragment1();
case 1:
return new Fragment2();
case 2:
return new Fragment3();
default:
return null;
}
}
@Override
public int getCount() {
return 3; // 3 Fragments in this example
}
}
So this is the most basic implementation of a FragmentStatePagerAdapter
and it is all you need to get it to work. I have not tested it but if necessary you should still be able to override getPageTitle()
like before.
Upvotes: 1