I don't know why my application behave in 2 different ways when i'm changing fragments. I have a menu drawer and inside a fragment i try to launch a new fragment on the same container using click event.
so when i use the menu to access to that fragment everything work well but when i try to access to the same fragment from another fragment (same container) i got on my screen both fragment overlapping.
Home fragment image
as you can see in this fragment i try to click on the bank icon to change the current fragment with another and that the result
fragment overlapping image
i'm using the fragment class to execute the click event here is the code :
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.nav_host_fragment, new AboutFragment());
ft.commit();
}
});
Please remember that when i access to the 2nd fragment using menu it works.
I have a fragment inside a group activity and I want to replace it with another fragment:
FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
SectionDescriptionFragment bdf = new SectionDescriptionFragment();
ft.replace(R.id.book_description_fragment, bdf);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
It works fine when it is done as a seperate project without using activity group, every thing works fine in log cat as control goes inside getview(), but no view is visible, not even any exception arises, I want the book detail fragment to be replaced by section detail fragment.
Xml of book detail fragment has id book_description_fragment and xml for section description fragment has id section_description_fragment.
The above code is in onClick method of an item, I want that when user taps on an item in horizontal scroll view, then the fragment changes.
Fragments that are hard coded in XML, cannot be replaced. If you need to replace a fragment with another, you should have added them dynamically, first of all.
Note: R.id.fragment_container is a layout or container of your choice in the activity you are bringing the fragment to.
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Please see this Question
You can only replace a "dynamically added fragment".
So, if you want to add a dynamic fragment, see this example.
I've made a gist with THE perfect method to manage fragment replacement and lifecycle.
It only replace the current fragment by a new one, if it's not the same and if it's not in backstack (in this case it will pop it).
It contain several option as if you want the fragment to be saved in backstack.
=> See Gist here
Using this and a single Activity, you may want to add this to your activity:
#Override
public void onBackPressed() {
int fragments = getSupportFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
finish();
return;
}
super.onBackPressed();
}
Use the below code in android.support.v4
FragmentTransaction ft1 = getFragmentManager().beginTransaction();
WebViewFragment w1 = new WebViewFragment();
w1.init(linkData.getLink());
ft1.addToBackStack(linkData.getName());
ft1.replace(R.id.listFragment, w1);
ft1.commit();
Use ViewPager. It's work for me.
final ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.vp_pager);
button = (Button)result.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewPager.setCurrentItem(1);
}
});
hope you are doing well.when I started work with Android Fragments then I was also having the same problem then I read about
1- How to switch fragment with other.
2- How to add fragment if Fragment container does not have any fragment.
then after some R&D, I created a function which helps me in many Projects till now and I am still using this simple function.
public void switchFragment(BaseFragment baseFragment) {
try {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
if (getSupportFragmentManager().findFragmentById(R.id.home_frame) == null) {
ft.add(R.id.home_frame, baseFragment);
} else {
ft.replace(R.id.home_frame, baseFragment);
}
ft.addToBackStack(null);
ft.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
enjoy your code time :)
you can use simple code its work for transaction
Fragment newFragment = new MainCategoryFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame_NavButtom, newFragment);
ft.commit();
You Can Use This code
((AppCompatActivity) getActivity()).getSupportFragmentManager().beginTransaction().replace(R.id.YourFrameLayout, new YourFragment()).commit();
or You Can This Use Code
YourFragment fragments=(YourFragment) getSupportFragmentManager().findFragmentById(R.id.FrameLayout);
if (fragments==null) {
getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayout, new Fragment_News()).commit();
}
I change fragment dynamically in single line code
It is work in any SDK version and androidx
I use navigation as BottomNavigationView
BottomNavigationView btn_nav;
FragmentFirst fragmentFirst;
FragmentSecond fragmentSecond;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
fragmentFirst = new FragmentFirst();
fragmentSecond = new FragmentSecond ();
changeFragment(fragmentFirst); // at first time load the fragmentFirst
btn_nav = findViewById(R.id.bottomNav);
btn_nav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch(menuItem.getItemId()){
case R.id.menu_first_frag:
changeFragment(fragmentFirst); // change fragmentFirst
break;
case R.id.menu_second_frag:
changeFragment(fragmentSecond); // change fragmentSecond
break;
default:
Toast.makeText(SearchActivity.this, "Click on wrong bottom SORRY!", Toast.LENGTH_SHORT).show();
}
return true;
}
});
}
public void changeFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout_changer, fragment).commit();
}
In kotlin you can do:
// instantiate the new fragment
val fragment: Fragment = ExampleFragment()
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.book_description_fragment, fragment)
transaction.addToBackStack("transaction_name")
// Commit the transaction
transaction.commit()
This will work if you're trying to change the fragment from another fragment.
Objects.requireNonNull(getActivity()).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.home_fragment_container,new NewFragment())
NOTE As stated in the above answers, You need to have dynamic fragments.
You can use fragment-ktx
// If you are in fragmet
childFragmentManager.beginTransaction()
// or if you are in activiry
supportFragmentManager.beginTransaction()
// Create and commit a new transaction
supportFragmentManager.commit {
setReorderingAllowed(true)
// Replace whatever is in the fragment_container view with this fragment
replace<ExampleFragment>(R.id.fragment_container)
}
To replace a fragment with another one do this, Note that R.id.fragment comes from the id that you give to the first tag of the fragment in the XML.
barAudioPlaying.setOnClickListener(view -> {
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment,new HomeFragment())
.commit();
i have a parent fragment and when i click in a button to open first fragment then click in button in first fragment to open a second fragment and from second fragment to third fragment and so on ....
i succeeded to do that but the application becomes very slow after launching multiple fragments
this is the code i used to launch any fragment
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
Fragment newFragment = new newFragment();
FragmentTransaction transaction =
getFragmentManager().beginTransaction();
transaction.replace(fragmentContainer.getId(), newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
});
When you are calling android.support.v4.app.FragmentManager then you must use getSupportFragmentManager().
public FragmentManager getSupportFragmentManager ()
Return the FragmentManager for interacting with fragments associated
with this activity.
If your new fragments are not transparent, I think you should check the overdraw of layouts.
The replace() needs to recreate the instance and reload data, maybe add() and hide() can help you.
i should use getActivity().getSupportFragmentManager() instead of getFragmentManager()
I have a Main Menu and created a fragment and its layout.
Now I can't seems to start fragment when user presses a button on main menu.
main menu has its own layout.
now is there anyway i could initialize it from a button?
Button bt = (Button)findViewById(R.id.button1);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainMenu.this, ExercisesFragment.class));
}
});
}
I tried it by this but it gives error saying
Fragment cannot be cast to android.app.Activity
You add fragments using fragment manager:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExercisesFragment fragment = new ExercisesFragment();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
read more on fragments, start here:
http://developer.android.com/guide/components/fragments.html
FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
ft.add(R.id.main_fragment, your_fragment);
ft.addToBackStack("ifneeded");
ft.commit();
You are doing it wrong! Intents are not used to load a fragment.
Solution is to use fragment transactions
to dynamically load the fragment you wish to bring into focus.
Here is what you need to do:
Have a container for the fragment inside the layout of you activity
Example: Assuming the layout resource of my activity is activity_main.xml, I would have a container like so
Follow this guide to create a Fragment
Assuming you already have a fragment setup with name AbcFragment, use fragment transactions to load the fragment into the container that you just created, whenever the user clicks on the button:
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getFragmentManager()
.beginTransaction()
.replace(R.id.fragment-container, new AbcFragment)
.commit();
}
});
when fragment use addToBackStack(null) method and click a method many times in an activity, the fragment page will save to back stack everytime, when I press back key, it will restore the same page, how to add the same fragment to stack just one time?
mSettingBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
SettingFragment settingFragment = new SettingFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.replace(R.id.left_framelayout, settingFragment);
transaction.addToBackStack(null);
transaction.commit();
}
});
When adding your Fragment to the backstack you should also pass a TAG to be able to identify that Fragment:
.addToBackStack(SettingsFragment.TAG);
Prior to adding the Fragment you will be able to check if this Fragment is allready in the backstack using :
getFragmentMangager().findFragmentByTag(SettingsFragment.TAG);
This will return null if the Fragment is not allready added.