I am creating a three tabs that contains one fragment each now I want to replace the first Tab\'s Fragment with a new Fragment within the same Tab. How can I do that with the ta
OK, several things:
You don't need both replace and remove. Replace effectively just removes the first fragment and adds the second in its place.
I suspect that your arguments are incorrect for the replace command. This is the proper form:
replace (int containerViewId, Fragment fragment)
You seem to be passing the id of the fragment itself, rather than the id of the container. The replace command takes the id of the container view and removes all fragments in that container before adding a new one. So if this was your layout:
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="com.example.stackoverflow.YourFragmentName"
android:id="@+id/main_fragment"
android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />
</LinearLayout>
You would use:
replace(R.id.container, mFragment);
and not
replace(R.id.main_fragment, mFragment);
Since you are trying to findFragmentById(R.id.main_fragment)
, I suspect that you have added this fragment to your XML layout file. If you have a fragment added directly in the XML, you cannot remove it programmatically at run time. In order to remove or replace fragments, you must have added them with a FragmentTransaction at run time.
EDIT:
Numbers 2 and 3 from my original answer still apply. You need to use the id of the containing ViewGroup for adding and replacing. In this case, that's your LinearLayout, R.id.Maincontainer, not R.id.main_fragment.
Also, as I said before, you cannot remove fragments that you have added directly in the XML. Your main_fragment
is added in the XML and therefore cannot be removed at run time.
Try this for your mainfragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/Maincontainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Switch Fragments">
</LinearLayout>
And this for your main_fragment class:
public class main_activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.mainfragment);
//Notice that I am adding this 1st fragment in the Activity and not the XML
main_fragment mainFragment = new main_fragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.Maincontainer, mainFragment);
ft.commit();
mButton = (Button) findViewById(R.id.btn);
mButton.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
Fragment mFragment = new third_fragment_view();
FragmentTransaction ft = getFragmentManager().beginTransaction();
//Replacing using the id of the container and not the fragment itself
ft.replace(R.id.Maincontainer, mFragment);
ft.addToBackStack(null);
ft.commit();
}
});
}
}
You have a structure like so:
TabActivity
-> Tab1 = FragmentActivity = MainFragment
-> Tab2
-> Tab3
From inside of MainFragment
you are trying to replace the contents of its container (itself).
It would be best if the MainFragment
called a customised TabActivity which in turn called a replace on it's container, either like so (Which may likely fall foul of the same problem as it's basically running the same code from the same place, but it should give you a basic idea of what I'm suggesting):
Fragment newFragment = new FragmentToChangeTo();
CustomTabActivity tabActivity = (CustomTabActivity) getActivity();
tabActivity.changeFragment(newFragment);
If this doesn't work try doing a similar thing but instead of calling the activity directly pass commands to it through Intents & Actions (or Bundles) containing information on what to change which container to.
I would have preferred to say /why/ Fragments don't work well with Fragment-in-fragment and related intricacies: check here to see why I suggest cutting fragments out of the control of fragments.
@theisenp i am creating a tab view in that when a button is clicked it must move to another screen when i try to implement it using the above code it is changing to another screen but the button is still visible with next screen and i want next screen should cover entire screen
public class Tab1Fragment extends Fragment {
LinearLayout mLayout;
/** (non-Javadoc)
* @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
*/
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
LinearLayout theLayout = (LinearLayout)inflater.inflate(R.layout.tab_frag1_layout, container, false);
// Register for the Button.OnClick event
Button b = (Button)theLayout.findViewById(R.id.button1);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment mFragment = new third_fragment_view();
android.support.v4.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, mFragment);
ft.addToBackStack(null);
ft.commit();
}
});
return theLayout;
}
}