I am using ViewPager / FragmentPagerAdapter in one of my application fragments to display different listviews in each page (see the picture below) :
The problem is that after i change the current view (Fragment) and i reopen it again, the listview isn't rendered (see the picture below) :
The behaviour is random, sometimes the listview are shown when i slide between different tabs/pages.
Here is my fragment code :
public class AstucesFragment extends Fragment implements ActionBar.TabListener {
ActionBar actionBar;
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
ViewPager mViewPager;
public static String[] tabslist = new String[5];
public AstucesFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_astuces, container, false);
tabslist[0] = getActivity().getResources().getString(R.string.astuces_quotidien);
tabslist[1] = getActivity().getResources().getString(R.string.astuces_resto);
tabslist[2] = getActivity().getResources().getString(R.string.astuces_loisirs);
tabslist[3] = getActivity().getResources().getString(R.string.astuces_transports);
tabslist[4] = getActivity().getResources().getString(R.string.astuces_tous);
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getActivity().getSupportFragmentManager());
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mViewPager = (ViewPager) view.findViewById(R.id.astuces_pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
actionBar.addTab(
actionBar.newTab()
.setCustomView(R.layout.fragment_astuces_tabs_quotidien)
.setTabListener(this));
actionBar.addTab(
actionBar.newTab()
.setCustomView(R.layout.fragment_astuces_tabs_resto)
.setTabListener(this));
actionBar.addTab(
actionBar.newTab()
.setCustomView(R.layout.fragment_astuces_tabs_loisirs)
.setTabListener(this));
actionBar.addTab(
actionBar.newTab()
.setCustomView(R.layout.fragment_astuces_tabs_transports)
.setTabListener(this));
actionBar.addTab(
actionBar.newTab()
.setCustomView(R.layout.fragment_astuces_tabs_tous)
.setTabListener(this));
return view;
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
Log.i("AstucesFragment","onTabSelected()");
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
Log.i("AstucesFragment","onTabReselected()");
}
/**
* A {#link android.support.v4.app.FragmentPagerAdapter} that returns a fragment corresponding to one of the primary
* sections of the app.
*/
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Log.i("AppSectionsPagerAdapter","Page ID : "+i);
// The other sections of the app are dummy placeholders.
Fragment fragment = new AstucesListFragment();
Bundle args = new Bundle();
args.putString(AstucesListFragment.ARG_PAGE_CAT, tabslist[i]);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return tabslist.length;
}
#Override
public CharSequence getPageTitle(int position) {
return tabslist[position];
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
}
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class AstucesListFragment extends Fragment {
public static final String ARG_PAGE_CAT = "page_cat";
private List<Astuce> astuceList = new ArrayList<Astuce>();
private ListView listView;
private AstuceAdapter adapter;
private AstuceDAO astuceDAO;
public AstucesListFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_astuces_page, container, false);
Bundle args = getArguments();
Log.i("AstucesListFragment","onCreateView()");
String theme = "";
if (args.getString(ARG_PAGE_CAT) == getString(R.string.astuces_quotidien)) theme = "Q";
else if (args.getString(ARG_PAGE_CAT) == getString(R.string.astuces_resto)) theme = "R";
else if (args.getString(ARG_PAGE_CAT) == getString(R.string.astuces_loisirs)) theme = "L";
else if (args.getString(ARG_PAGE_CAT) == getString(R.string.astuces_transports)) theme = "T";
else theme = "";
astuceDAO = new AstuceDAO();
astuceList = astuceDAO.findAstuceByTheme(theme);
listView = (ListView) rootView.findViewById(R.id.astuces_list);
adapter = new AstuceAdapter(getActivity(), astuceList);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
return rootView;
}
}
}
How can i fix this problem ?
If you want your fragments to maintain its state even after changing the tabs,
Try this,
mViewPager.setOffscreenPageLimit(5); //as you have 5 fragments
But this will make the activity to initialize all the fragments at the same time when the activity is invoked.
Another method is to use FragmentStatePagerAdapter instead of FragmentPagerAdapter. Refer,
http://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html
You are not comparing strings correctly. When comparing two strings you need to use equals() method instead of == operator. So in onCreateView() in AstucesListFragment replace
if (args.getString(ARG_PAGE_CAT) == getString(R.string.astuces_quotidien)) theme = "Q";
else if (args.getString(ARG_PAGE_CAT) == getString(R.string.astuces_resto)) theme = "R";
else if (args.getString(ARG_PAGE_CAT) == getString(R.string.astuces_loisirs)) theme = "L";
else if (args.getString(ARG_PAGE_CAT) == getString(R.string.astuces_transports)) theme = "T";
else theme = "";
with
if (args.getString(ARG_PAGE_CAT).equals(getString(R.string.astuces_quotidien))) theme = "Q";
else if (args.getString(ARG_PAGE_CAT).equals( getString(R.string.astuces_resto))) theme = "R";
else if (args.getString(ARG_PAGE_CAT).equals( getString(R.string.astuces_loisirs))) theme = "L";
else if (args.getString(ARG_PAGE_CAT).equals( getString(R.string.astuces_transports))) theme = "T";
else theme = "";
This may solve your problem as the results of == operators will be inconsistent as both the strings may or may not point to same object.
Related
I'm using a SlidingTabLayout (from the Google sources) in my app to navigate between different fragments.
I can swipe between contents just fine, but the problem I'm facing is the title of the Action bar that is acting weird.
Suppose that I have two tabs with two titles ('First Title' and 'Second Title') :
| Action bar |
| First Title | Second Title |
When I first enter the Fragment containing the SlidingTabLayout, the title of the Actionbar is like this :
| Firs... |
| First Title | Second Title |
When I swipe (to the second tab for example), the title of the actionbar becomes :
| Second Title |
| First Title | Second Title |
And stays like this. It seems that the Actionbar takes the title of the last Fragment loaded when I swipe at least once.
What I want is this :
I want to show a 'Main Title' in the Actionbar that never changes no matter what the title in the SlidingTabLayout is.
Here are some portions of my code:
** Fragment containing the SlidingTabLayout:
private String mainTitle;
....
#Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
// The mainTitle is given to this fragment by another fragment
Bundle args = getArguments();
if (args != null) {
mainTitle = args.getString("TITLE");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.layout, container, false);
mViewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
mSlidingLayout = (SlidingTabLayout) rootView.findViewById(R.id.sliding_layout);
List<Fragment> listFragments = new ArrayList<>();
List<String> listTitles = new ArrayList<>();
for (int i = 0; i < mSize; i++) {
Bundle bundle = new Bundle();
....
listFragments.add(Fragment.instanciate(getActivity(), CustomFragment.class.getName(), bundle));
listTitles.add("...");
}
mViewPager.setAdapter(new PagerAdapter(getChildFragmentManager(), listFragments, listTitles));
mSlidingLayout.setDistributedEvenly(true);
mSlidingLayout.setViewPager(mViewPager);
return rootView;
}
#Override
public void onResume() {
super.onResume();
// I TRY TO SET THE TITLE HERE !!
getActivity().getSupportActionBar().setTitle(mainTitle);
}
** Adapter:
class PagerAdapter extends FragmentPagerAdapter {
List<Fragment> fragments;
List<String> titles;
...
#Override
public Fragment getItem(int position) {
Fragment fragment = fragments.get(position);
return fragment;
}
#Override
public CharSequence getPageTitle(int position) {
// maybe the problem is in this method.
// this method is supposed to provide the titles for the tab
// but maybe it's also changing the actionbar title
return titles.get(position);
}
I'm setting the title of the ActionBar in the onResume method every time I enter a Fragment.
Thanks !
EDIT 1 :
I tried using the new SlidingTabLayout which I've got from the Google I/O, and the result is still the same !
It seems that the Title in the ActionBar is a hint at first, and then it changes to the last loaded fragment when I swipe to another fragment.
It's like it's loading fragment, and each time a fragment is loaded, the title in the ActionBar is overridden with the title of that fragment.
EDIT 2 :
I changed my code to post the latest version of it (I'm using now a SlidingTabLayout) and to show how I get my mainTitle.
you can use below code it works fine for me
public class MatchesActivity extends AppCompatActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
FloatingActionButton skipButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_matches);
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
skipButton = (FloatingActionButton) findViewById(R.id.skip_next);
skipButton.setVisibility(View.GONE);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(1);
mViewPager.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
});
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
actionBar.addTab(
actionBar.newTab().setText("MATCHES")
.setTabListener(this));
actionBar.addTab(
actionBar.newTab().setText("PINS")
.setTabListener(this));
actionBar.addTab(
actionBar.newTab().setText("CHATS")
.setTabListener(this));
}
#Override
public void onBackPressed() {
startActivity(new Intent(MatchesActivity.this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK & Intent.FLAG_ACTIVITY_CLEAR_TOP));
MatchesActivity.this.finish();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new MatchesFragment();
case 1:
return new PinsFragment();
case 2:
return new ConversationFragment();
default:
return new MatchesFragment();
}
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
}
I am posting here a code of mine.It worked for me.Make required changes in it and try it.I used PagerSlidingTabStrip library in it.
public class DealFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_deal, container, false);
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setAdapter(new SampleFragmentPagerAdapter(getChildFragmentManager()));
PagerSlidingTabStrip tabsStrip = (PagerSlidingTabStrip)view.findViewById(R.id.tabs);
tabsStrip.setBackgroundColor(Color.parseColor("#333333"));
// Attach the view pager to the tab strip
tabsStrip.setViewPager(viewPager);
return view;
}
public class SampleFragmentPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 2;
private final String tabTitles[] = new String[] { "Today's Deals", "Deals Close By" };
public SampleFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
if(position==0)
{
return new TodaysDeal();
}
else
{
return new DealsCloseBy();
}
}
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
}
}
hope it might help you.
The actionBar title doesn't change because onResume() is not called the time you swipe back.
It's because ViewPager doesn't call fragment's onResume the second time. Even though in reality the fragment is resumed.
What you can do is to move the setting of your actionbar title in your parent fragment (that contains pagertabstrip) to onCreateView instead.
For your reference:
** Fragment containing the PagerTabStrip:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.layout, container, false);
mViewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
List<Fragment> listFragments = new ArrayList<>();
List<String> listTitles = new ArrayList<>();
...
// HERE's what you want
final ActionBar actionBar = getActivity().getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(R.string.main_title);
}
mViewPager.setAdapter(new PagerAdapter(getChildFragmentManager(), listFragments));
return rootView;
}
Found it !
It was really dumb of me (it explains why others didn't have this problem)
I was setting the title also in each of the Fragments (even those contained in the Tabs), so when I swiped, the onResume on those Fragments was called and it changed the title in the ActionBar...
Thank you all for the help, I appreciate it !
I'm using tab navigation in my app. Each tab has a form that preforms similar tasks, so I'm using the same fragment but simply hiding/showing bits of it. It appears that the ViewPager is instantiating 3 different copies of the fragment, and then switching between them when the user changes tabs. Since all the fragments are the same, I'd like to pass the state of the fields between them. This way when a user changes to a different tab, the information they filled in on the previous tab is present on the new tab.
Is there a preferred method to passing data in this way?
The dumbed down code looks like this...
public class MainActivity extends Activity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager(), this);
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 void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private Context context;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
public SectionsPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getResources().getString(R.string.tab_one_title);
case 1:
return getResources().getString(R.string.tab_two_title);
case 2:
return getResources().getString(R.string.tab_three_title);
}
return null;
}
}
public class MainFragment extends Fragment {
private static final String ARG_SECTION_TYPE = "section type";
public MainFragment(){}
public MainFragment(int sectionNumber) {
Bundle args = new Bundle();
args.putInt(ARG_SECTION_TYPE, sectionNumber);
setArguments(args);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
//setup the view
switch(getArguments().getInt(ARG_SECTION_TYPE)) {
//hide or show fields based on page number.
}
return rootView;
}
}
}
If the user modifies a field on page 1, i'd like the information to also show up on page 2, and page 3. What's the preferred method to accomplish this?
Data-Push Method: LocalBroadcastManager
Each fragment registers a broadcastReceiver, and when data changes broadcast it to all registered receivers. It's the sender of the data that decides when the receiving objects are updated.
For an example of implementing a LocalBroadcastManager: how to use LocalBroadcastManager?
Data-Pull Method: Central repository.
Send the data to an intermediary object (the central repository) to store the data. Then each fragment can poll the object whenever it needs to be updated with the latest data.
In this case, the activity would reference the object, and each fragment would call to the repository by ((MyInterface) getActivity).mDataObject.data....
I have 2 fragments (tabs) that share some data. When one changes the data, I'd like to have that reflected on the other tab. I researched this on stackOverflow and I think the relevant answer has to do with a .notifyDataSetChanged() call, but I can't make it work. Here's the relevant code...
public class EnterCourseData extends FragmentActivity implements ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Pars", "Handicaps" };
private int courseNumber, teeNumber;
private Tee tee;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_tees);
// Initilization
Intent mIntent = getIntent();
courseNumber = mIntent.getIntExtra("courseNumber",0);
Course course = Global.getCourse(courseNumber);
teeNumber = mIntent.getIntExtra("teeNumber",0);
tee = course.getTee(teeNumber);
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager(), courseNumber, teeNumber);
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));
}
/**
* on swiping the viewpager make respective tab selected
* */
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) {
}
});
}
and further down, here is the onClick method that necessitates the refresh...
public void savePars(View view){
tee.setSlope(Integer.parseInt(((EditText) findViewById(R.id.enter_tee_slope)).getText().toString()));
tee.setRating(Double.parseDouble(((EditText) findViewById(R.id.enter_tee_rating)).getText().toString()));
mAdapter.notifyDataSetChanged();
}
Here is the TabsPagerAdapter...
public class TabsPagerAdapter extends FragmentPagerAdapter {
int courseNumber, teeNumber;
public TabsPagerAdapter(FragmentManager fm, int courseNumber, int teeNumber) {
super(fm);
this.courseNumber = courseNumber;
this.teeNumber = teeNumber;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Par Entry activity
Fragment parFragment = new ParFragment();
Bundle args = new Bundle();
args.putInt(ParFragment.ARG_COURSE_NUMBER, courseNumber);
args.putInt(ParFragment.ARG_TEE_NUMBER, teeNumber);
parFragment.setArguments(args);
return parFragment;
case 1:
// Handicap Entry fragment activity
Fragment hcpFragment = new HandicapFragment();
args = new Bundle();
args.putInt(HandicapFragment.ARG_COURSE_NUMBER, courseNumber);
args.putInt(HandicapFragment.ARG_TEE_NUMBER, teeNumber);
hcpFragment.setArguments(args);
return hcpFragment;
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
}
Here is one Fragment...
public class ParFragment extends Fragment {
public static final String ARG_COURSE_NUMBER = "courseNumber", ARG_TEE_NUMBER = "teeNumber";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_par, container, false);
Bundle args = getArguments();
Course course = Global.getCourse(args.getInt(ARG_COURSE_NUMBER));
((TextView) rootView.findViewById(R.id.display_course_name)).setText(course.getName());
Tee tee = course.getTee(args.getInt(ARG_TEE_NUMBER));
((TextView) rootView.findViewById(R.id.display_tee_name)).setText(tee.getTeeName());
((TextView) rootView.findViewById(R.id.enter_tee_slope)).setText(Integer.toString(tee.getSlope()));
((TextView) rootView.findViewById(R.id.enter_tee_rating)).setText(Double.toString(tee.getRating()));
return rootView;
}
}
And here is the other...
public class HandicapFragment extends Fragment {
public static final String ARG_COURSE_NUMBER = "courseNumber", ARG_TEE_NUMBER = "teeNumber";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_handicap, container, false);
Bundle args = getArguments();
Course course = Global.getCourse(args.getInt(ARG_COURSE_NUMBER));
((TextView) rootView.findViewById(R.id.display_course_name)).setText(course.getName());
Tee tee = course.getTee(args.getInt(ARG_TEE_NUMBER));
((TextView) rootView.findViewById(R.id.display_tee_name)).setText(tee.getTeeName());
((TextView) rootView.findViewById(R.id.enter_tee_slope)).setText(Integer.toString(tee.getSlope()));
((TextView) rootView.findViewById(R.id.enter_tee_rating)).setText(Double.toString(tee.getRating()));
return rootView;
}
}
When the button is clicked, I want to save the values and I want these values to show up on the other fragment.
Help a noob out.
Thanks
You need to communicate between fragments, but a fragment cannot directly communicate with other fragment, all the communication should be done through the activity which holds these fragments.
The steps to follow are :
Define an Interface in the fragment where you have implemented the onClickListener (let it be Fragment A)
Implement the Interface in the activity which holds these fragments
In the method overridden, retrieve the fragment instance from the viewpager adapter and deliver a message to Fragment B by calling it's public methods.
refer this answer to retrieve fragment instance from adapter
For more details about Communicating with Other Fragments, refer here
So there is a trick: just let the fragments have the object reference of one another and call the other's function to load data when you handle the onClickListener of the button.
E.g:
protected void onClickListener(View view) {
if (view == myButton) {
// Do other stuffs here
fragment1.reloadData();
}
}
P/S : I re-post this as answer to have the code formatter.
I created an activity with ActionBar and tabs using the Eclipse wizard. I want to show ListViews inside my three tabs but if they are not shown when I run my app.
The code for the activity with the Tabs:
public class CreateProjectManually extends FragmentActivity implements ActionBar.TabListener {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide fragments for each of the
* sections. We use a {#link android.support.v4.app.FragmentPagerAdapter} derivative, which will
* keep every loaded fragment in memory. If this becomes too memory intensive, it may be best
* to switch to a {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_project_manually);
// Create the adapter that will return a fragment for each of the three primary sections
// of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the action bar.
final ActionBar actionBar = getActionBar();
// set the app icon as an action to go home
actionBar.setDisplayHomeAsUpEnabled(true);
//enable tabs in actionbar
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// 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
// listener for when this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
/**
* Actionbar
* */
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_save:
//TODO Speichern implementieren
Toast.makeText(getBaseContext(), "Speichern",Toast.LENGTH_LONG).show();
break;
case android.R.id.home:
// app icon in action bar clicked; go home
Intent intent = new Intent(this, ProjectList.class);
intent.putExtra("Uniqid","From_CreateProjectManually_Activity");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
return true;
default:
break;
}
return true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_create_project_manually, menu);
return true;
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#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 onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to one of the primary
* sections of the app.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0: return getString(R.string.building).toUpperCase();
case 1: return getString(R.string.room).toUpperCase();
case 2: return getString(R.string.devices).toUpperCase();
}
return null;
}
}
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
public DummySectionFragment() {
}
public static final String ARG_SECTION_NUMBER = "section_number";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return (LinearLayout) inflater.inflate(R.layout.listviews, container, false);
}
}
}
And the XML-file for the layout with the ListView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="259dp" >
</ListView>
</LinearLayout>
</LinearLayout>
The TextView is shown but the ListView not. What is the problem?
First you have to create your adapter for the list view that yo have with it's own custom row and find it's id in the onCreateView method based on on the root view like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_calendar_dummy,
container, false);
/*TextView dummyTextView = (TextView) rootView
.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)) + "HOLA");*/
//getFavorito(ARG_SECTION_NUMBER);
//asyncFavorite().execute(ARG_SECTION_NUMBER);
lista = (ListView) rootView.findViewById(R.id.Your own list);
loadingLista = (RelativeLayout) rootView.findViewById(R.id.loadingLista);
int mes = getArguments().getInt(ARG_SECTION_NUMBER);
new asyncFavorite().execute(Integer.toString(mes));
Log.i("mfb", "puse el-----------------" + Integer.toString(mes));
return rootView;
}
after this you have to create a method to inflate your list, create an array list of your object that contains all the elements of the list and use it to inflate all the rows:
m_orders = new ArrayList<Order>();
//JSONObject data = new JSONObject(Fetcher.getMonthBirthday(FBAccount, params[0]));
//resData = data.getJSONArray("data");
//Log.i("mfb", "RESDATA::::::::::" + resData + "////////////////////" +Index.userID);
JSONObject objeto = null;
String nombre = "";
String cumpliendo = "";
String mes = "";
String dia = "";
String uuid = "";
String favorite = "";
String ownerID = "";
int mesNumero = 0;
String[] cumple = null;
String pasoMes = "";
for(int i = 0; i<resData.length(); i++){
objeto = resData.getJSONObject(i);
nombre = objeto.getString("name");
cumpliendo = objeto.getString("edad");
cumple = objeto.getString("birthday").split("-");
dia = cumple[2];
pasoMes = cumple[1];
mesNumero = Integer.parseInt(pasoMes);
//mes = getMes(mesNumero);
uuid = objeto.getString("uuid");
favorite = "1";
ownerID = objeto.getString("user_id");
m_orders.add(i, new Order(""+nombre, ""+cumpliendo, ""+mes, ""+dia, "" + uuid, ""+favorite, ""+ownerID, "" + FBAccount));
//Log.i("mfb", "HH " + nombre);
}
the you have to set the adapter to your list
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Log.v("mfb", " Runnable "+m_orders.size());
adapterOrder = new orderItemAdapter(activity.getApplicationContext(), android.R.layout.simple_list_item_1, m_orders);
lista.setAdapter(adapterOrder);
adapterOrder.notifyDataSetChanged();
}catch (NullPointerException e){
Log.e("Error", " generateAdapter NullPointerException ERROR => "+e.getMessage());
}catch (Exception e) {
// TODO: handle exception
Log.e("Error", " generateAdapter Exception ERROR => "+e.getMessage());
}
}
});
the adapter is something like this:
public class orderItemAdapter extends ArrayAdapter<Order>{
public ArrayList<Order> orders;
LayoutInflater inflater = null;
public orderItemAdapter(Context context, int textViewResourceId, ArrayList<Order> orders){
super(context, textViewResourceId, orders);
this.orders = orders;
Log.v("mfb", "orderItem "+this.orders.size());
}
public void add(int index, Order order){
this.orders.add(index, order);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View vi=convertView;
LayoutInflater inflater = null;
if(convertView==null){
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vi = inflater.inflate(R.layout.list_user, null);
}
Order order = orders.get(position);
if(order != null){
TextView nombre = (TextView)vi.findViewById(R.id.nombre);
TextView edadCumplir = (TextView)vi.findViewById(R.id.edadCumplir);
//TextView mes = (TextView)vi.findViewById(R.id.mes);
TextView dia = (TextView)vi.findViewById(R.id.dia);
//Log.v("mfb", " order position => "+position);
if(nombre != null){
nombre.setText(orders.get(position).getNombre());
//Log.v("mfb", "orderItemAdapter nombre =>" + nombre.getText());
}
if(edadCumplir != null){
edadCumplir.setText("Turning " + orders.get(position).getCumpliendo());
}
/*if(mes != null){
mes.setText(orders.get(position).getMes());
}*/
if(dia != null){
dia.setText(orders.get(position).getDia());
}
}
return vi;
}
}
For ActionBarSherlock I would like to have (Action Bar) Tabs + Pager. I use Fragments inside that pager container. I already got the examples of http://actionbarsherlock.com/ working, but I can't manage to get a details fragment inside that pager container when I would click on let's say a listitem in the first fragment.
Is it impossible to have something like this:
Activity with Tabs and pager container
Fragment A inside pager container under Tab1
Click on something in Fragment A and show Fragment B in same pager container under Tab1.
Fragment A is then not visible, only Fragment B is visible, but also all the Tabs.
At the moment I think only a new activity (which would hold Fragment B inside it) can be started after clicking something in Fragment A.
Here is my solution for the (Tabs + Fragment + ViewPager) it is works for me as i wanted,
hope that works for you as well
here is the xml file
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="5" />
<FrameLayout
android:id="#+id/fragment_details"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="4.3" />
</LinearLayout>
here is the code for MainActivity.java I'll post relevant code only so you'll have to manage it
public class MainActivity extends FragmentActivity implements
DialogInterface.OnDismissListener, TabDataResponder {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
artistTab = getSupportActionBar().newTab().setText(
R.string.tab_name_artist);
albumTab = getSupportActionBar().newTab().setText(
R.string.tab_name_album);
songTab = getSupportActionBar().newTab().setText(
R.string.tab_name_songs);
map = new HashMap<String, Integer>();
mViewPager = (ViewPager) findViewById(R.id.pager);
FrameLayout deatil = (FrameLayout) findViewById(R.id.fragment_details);
mDualPane = (deatil != null) && (deatil.getVisibility() == View.VISIBLE);
mTabsAdapter = new TabsAdapter(this, getSupportActionBar(), mViewPager);
if (savedInstanceState != null) {
flag = true;
index = savedInstanceState.getInt("index");
}
setUpTabView();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("index", getSupportActionBar()
.getSelectedNavigationIndex());
}
private void setUpTabView() {
mTabsAdapter.addTab(artistTab, ArtistFragment.class, null);
mTabsAdapter.addTab(albumTab, AlbumFragment.class, null);
mTabsAdapter.addTab(songTab, SongFragment.class, null);
getSupportActionBar().setSelectedNavigationItem(index);
}
public static class TabsAdapter extends FragmentPagerAdapter implements
ViewPager.OnPageChangeListener, ActionBar.TabListener {
private FragmentActivity mContext;
private ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<String> mTabs = new ArrayList<String>();
private TabDataResponder responder;
public TabsAdapter(FragmentActivity activity, ActionBar actionBar,
ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = actionBar;
mViewPager = pager;
// TabDataResponder is an interface which is implemented in MainActivity
// You can find implementation # the last
responder = (TabDataResponder) activity;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
//I have used map to save state of the fragment
map.put(SongFragment.TYPE_FRAGMENT.trim(), 0);
map.put(AlbumFragment.TYPE_FRAGMENT.trim(), 0);
map.put(ArtistFragment.TYPE_FRAGMENT.trim(), 0);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
mTabs.add(clss.getName());
// mArgs.add(args);
mActionBar.addTab(tab.setTabListener(this));
notifyDataSetChanged();
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
return Fragment
.instantiate(mContext, mTabs.get(position), /*
* mArgs.get(
* position)
*/null);
}
#Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Log.i(TAG, "PageSelected....");
mActionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
Log.i(TAG, "ScrollSateChanged....");
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
String a = null;
if (mDualPane) {
a = mTabs.get(tab.getPosition());
responder.loadData(a, map.get(a));
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Log.i(TAG, "Tab is released now....");
}
}
#Override
public void onDismiss(DialogInterface dialog) {
setUpTabView();
}
//This interface must be call from fragment class
//# the time of event you want to show detail
// pass the class name in the type argument using class.getName() method
#Override
public void loadData(String type, int index) {
DetailFragment viewer = (DetailFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment_details);
if (mDualPane) {
if (viewer == null || viewer.getShownIndex() != index
|| viewer.getTypeFragment() != type) {
DetailFragment df = DetailFragment.newInstance(index, type);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_details, df)
.setTransition(
FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
map.put(type.trim(), index);
}
} else {
Intent intent = new Intent();
intent.setClass(MainActivity.this, DetailActivity.class);
intent.putExtra("index", index);
intent.putExtra("type", type);
startActivity(intent);
}
}
}
and here is how i deal with detail fragment not very efficient but kind of working
public class DetailFragment extends Fragment{
public static DetailFragment newInstance(int index, String TYPE_FRAGMENT) {
DetailFragment f = new DetailFragment();
// Supply index input as an argument.
Bundle args = new Bundle();
args.putInt("index", index);
args.putString("type", TYPE_FRAGMENT);
f.setArguments(args);
return f;
}
public int getShownIndex() {
return getArguments().getInt("index", 0);
}
public String getTypeFragment(){
String a = getArguments().getString("type");
return a;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//template is blank layout
View view = inflater.inflate(R.layout.template, container, false);
if(getTypeFragment().equals(ArtistFragment.TYPE_FRAGMENT)){
view = null;
view = inflater.inflate(R.layout.artist_details, container, false);
//....
}
else if(getTypeFragment().equals(AlbumFragment.TYPE_FRAGMENT)){
//do's for album fragment
}
else if(getTypeFragment().equals(SongFragment.TYPE_FRAGMENT)){
//do's for song fragment
}
return view;
}
}
do not save the state of tab in their individual fragment it will conflict, we are already doing it here
EDIT:
Cheered too soon. Now the details_container is not a viewpager and I cannot use it to 'swipe tabs'.
Found it! Just had to define two FrameLayouts, with in the first one the ViewPager and in the second the details fragments can be 'loaded'. This is done by adding fragments dynamically and replace them.
First the two FrameLayouts:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fadingEdge="none" >
<FrameLayout
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
<FrameLayout
android:id="#+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Then replace a fragment dynamically:
// Create new fragment and transaction
Fragment detailsFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment container view with this fragment
// and add the transaction to the back stack
transaction.replace(R.id.details_container, detailsFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Very simple and I don't understand why it took me hours to figure this out..
I still did not find a possibility to have a Pager container where fragments should be loaded in and also keep the (ActionBar) Tabs. I have however found a really dirty solution to acomplish this, with starting intens (Main Activity with the Tabs) and finishing the previous ones when the backbutton doesn't need it anymore.
I adapted the code from ABS: Support Demos - Tabs and Pager. But again it's really dirty:
LoaderCursorSupport.CursorLoaderListFragment under Tab2
#Override public void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent();
intent.setClass(getActivity(), ActionBarTabsPager.class);
intent.putExtra("index", position);
intent.putExtra("fragment", "details");
intent.putExtra("tab", 1);
ActionBarTabsPager.mPreviousActivity = getActivity();
startActivity(intent);
ActionBarTabsPager (Main Activity with Tabs)
public class ActionBarTabsPager extends FragmentActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
static Activity mPreviousActivity;
static Activity mActivity;
static int mTabPosition = -1;
static Boolean mTabRefreshed = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actionbar_tabs_pager);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = getSupportActionBar().newTab().setText("Tab 1");
ActionBar.Tab tab2 = getSupportActionBar().newTab().setText("Tab 2");
ActionBar.Tab tab3 = getSupportActionBar().newTab().setText("Tab 3");
ActionBar.Tab tab4 = getSupportActionBar().newTab().setText("Tab 4");
String fragment = "";
try {
Bundle bundle = this.getIntent().getExtras();
fragment = bundle.getString("fragment");
mTabPosition = bundle.getInt("tab");
} catch (Exception ex) {
}
mViewPager = (ViewPager) findViewById(R.id.pager);
mTabsAdapter = new TabsAdapter(this, getSupportActionBar(), mViewPager);
mTabsAdapter.addTab(tab1, FragmentStackSupport.CountingFragment.class);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ECLAIR) {
mTabsAdapter.addTab(tab2, FragmentStackSupport.CountingFragment.class);
mTabsAdapter.addTab(tab3, FragmentStackSupport.CountingFragment.class);
mTabsAdapter.addTab(tab4, FragmentStackSupport.CountingFragment.class);
} else {
if (!fragment.contains("details")) {
mTabsAdapter.addTab(tab2, LoaderCursorSupport.CursorLoaderListFragment.class);
} else {
mTabsAdapter.addTab(tab2, ExampleFragment.class);
}
mTabsAdapter.addTab(tab3, LoaderCustomSupport.AppListFragment.class);
mTabsAdapter.addTab(tab4, LoaderThrottleSupport.ThrottledLoaderListFragment.class);
}
if (savedInstanceState != null) {
getSupportActionBar().setSelectedNavigationItem(savedInstanceState.getInt("index"));
}
if (mTabPosition > -1) {
mTabsAdapter.setPrimaryItem(mTabPosition);
mActivity = this;
}
}
Inside this Class there's a TabsAdapter
public static class TabsAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, ActionBar.TabListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<String> mTabs = new ArrayList<String>();
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mTabPosition > -1 && mTabRefreshed) {
int tabPosition = tab.getPosition();
if (mTabPosition != tabPosition) {
if (mPreviousActivity != null) {
mPreviousActivity.finish();
mTabRefreshed = false;
mPreviousActivity = null;
mTabPosition = -1;
Intent intent = new Intent();
intent.setClass(mContext, ActionBarTabsPager.class);
intent.putExtra("fragment", "home");
intent.putExtra("tab", tabPosition);
mActivity.startActivity(intent);
mActivity.finish();
}
}
}
mViewPager.setCurrentItem(tab.getPosition());
}
Can this be done simpler? Or should I just give up on having Tabs together with fragment history? This was done before Android 3.0 with ActivityGroups and Activities, but it seems this can't be done with fragments.
I found the other good example of the same implementation in hear... https://github.com/UweTrottmann/SeriesGuide
In this example under package com.battlelancer.seriesguide.ui
you can find UpcomingRecentActivity.java, and UpcomingFragment.java
and layout upcoming_multipan.xml
this example works for me...
I got one problem while adding different content for detail-fragment the different tabs, it gives me class-cast-exception
so i implemented a common detalFragment class and created separate layout in onCreateView method
but the only one problem i found is layout is not changing on tab switched, may be need to do it by implementing some listener
I'll tell you when i found the answer.