Im currently working on a sample app that will be using fragments, but im having a little problem regarding changing the fragment.
My default layout for my fragment is fragmentOne (see code below).
<fragment
android:id="#+id/fplace"
android:layout_width="match_parent"
android:layout_height="498dp"
android:name="layout.FragmentOne"
tools:layout="#layout/fragment_fragment_one" />
and that's working correctly.
but when im changing the fragment it appends. the behavior must replace the fragment not append.
here is my code for the activity (see code below).
public void onClick(View view) {
Button button = (Button) view;
Fragment fragment = null;
switch (button.getId()) {
case R.id.f1:
fragment = new FragmentOne();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fplace, fragment);
ft.commit();
break;
case R.id.f2:
fragment = new FragmentTwo();
fm = getFragmentManager();
ft = fm.beginTransaction();
ft.replace(R.id.fplace, fragment);
ft.commit();
break;
}
}
and from the fragment one i am loading the data from the onCreateView() which is working correctly. the main problem is the fragment appends not replace.
(see photo below)
the red and yellow must be replaced by the blue colored fragment
As Mike said in comment
You cannot remove/replace Fragments that are declared in your layout.
So here is solution for you. Instead of fragment in xml use framelayout as container which will hold the fragment
use this instead of fragment in xml
<FrameLayout
android:id="#+id/fplace"
android:layout_width="match_parent"
android:layout_height="498dp"
/>
Hope this will help you.
declare a new fragmenttransaction in the second case dont use the fragment transaction that is used in the first case
Related
Here's my Flow/Structure:
Activity
Fragment
Same Fragment within it.
I have overriden removeCurrentFragment() method which does go back functionality by removing Fragment by ID as follows -
#Override
public void removeCurrentFragment() {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.fragment);
if (currentFrag != null)
transaction.remove(currentFrag);
transaction.commit();
}
It seems, when this happens, as ID of both fragment is same, it creates blank view.
If more details are required, please feel free to ask in comments. I will edit question as per required details.
I thought it was related to remove fragment, But I made new fragment with separate XML, still I am having the same issue.
I have parent fragment with pagination (as I need horizontal page scroll) in it have the child fragment, when clicking on child fragment button new fragment is replaced so when it is removed the X and Y of the child fragment is also disturbed.
here is the before and after screenshot of the x and y axis of child fragment.
Before
After
can any one suggest what could be the issue?
You have to use a tag to load the Fragment, and then use that same tag again to remove it.
For example, to add the Fragment:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
fragmentManager.popBackStack(tag, androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
ft.setCustomAnimations(R.anim.enter, R.anim.exit);
ft.add(containerId, fragment, tag);
ft.addToBackStack(tag);
ft.commit();
To remove it, again use the same tag:
if (fragmentManager.findFragmentByTag(currentTag) != null) {
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.remove(fragmentManager.findFragmentByTag(currentTag));
ft.commit();
}
I found so many similar questions and so many different answers, but none of them helped me. I will try to post a clear question to get a clear answer if it's possible.
So I have an Activity that has a ViewPager with FragmentStatePagerAdapter containing (for now) only one fragment (HomeScreenFragment).
Inside HomeScreenFragment I have a RecyclerView with a list of several kind of different icons which should open a different fragment for each item click.
HomeScreenFragment has a FrameLayout as a root layout with id name "container". This is the method I'm calling to replace HomeScreenFragment with MainTypesFragment in this case:
private void openAllTypesFragment() {
MainTypesFragment fragment = new MainTypesFragment();
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, fragment);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.addToBackStack(HomeScreenFragment.class.getName());
transaction.commit();
eventBus.post(new Event(null, Event.EVENT_FRAGMENT));
}
Since FragmentStatePagerAdapter is initialized in MainActivity, I'm sending an event which will MainActivity catch and call adapter.notifyDataSetChanged();
Doing it this way, nothing happens.. I tried with getChildFragmentManager() instead of getActivity().getSupportFragmentManager() and in that case, previous fragment (HomeScreenFragment) is visible underneath new one (MainTypesFragment)..
Any ideas what am I doing wrong here?
The container you are using is wrong.Maintain one container in the activity xml and use that container to load all the fragments.
transaction.replace(R.id.container, fragment);
The container here is to be the activity container in which viewpager and other views should be present.
You can try my code :
private void addFilmDetailFragment(Movie movie){
android.support.v4.app.FragmentManager fragmentManager = getFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FilmDetailFragment fragment = new FilmDetailFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("movie", movie); // Key, value
fragment.setArguments(bundle);
fragmentTransaction.replace(R.id.mainContentStore, fragment);
// fragmentTransaction.replace(R.id.mainContent, fragment, Config.TAG_FILM_DETAIL);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
In a fragment of viewpager :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainContentStore"
android:layout_width="match_parent"
android:layout_gravity="center"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerFilm"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
It worked for me, i hope it will help your problem!
You need container inside activity for ViewPager and inside fragments(pages), containers for opening new fragments inside pages.
And if you want to open new fragment you should user something like this
in page fragment
getChildFragmentManager().beginTransaction()
.replace(R.id.page_fragment_container, fragment)
.addToBackStack(name)
.commit()
where R.id.page_fragment_container container inside page fragment.
ask for helping to do these steps please:
I have on main activity has one Relative layout
<RelativeLayout
android:id="#+id/main_framelayout_small_contain"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
1.when activity starts it replaces RelativeLayout with fragment (f1)
2.(f1) has listview when user click I have to show another fragment (f2)
in f1 place so I use these method in MainActivity
public void set_fragment_subject(String path)
{
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft= fragmentManager.beginTransaction();
Fragment_subjects f1 = new Fragment_subjects(path);
Fragment_season f2 = new Fragment_season();
ft.add(R.id.main_framelayout_small_contain,f1);
ft.hide(f2);
ft.commit();
}
may it looks strange but I do this after search because I want to retain f1's data when press backbutton.
The problem appears When user clicks in f1 , Activity shows f2 but over the f1.
Sorry to take long time ,Any one can help to do what I want correctly,Thanks
Hello #Ghadeer here you can access fragment as tow way one was the normal replace old fragment and another is maintain back stack, But I think you have need tow second way because you want to first fragment data as, so follow the following step for do it,
Please take frame layout instead of Relative layout
<FrameLayout
android:layout_width="match_parent"
android:id="#+id/main_framelayout_small_contain"
android:layout_height="match_parent"></FrameLayout>
Here I have created tow method we will use in our code so put in your activity where you start your fragment :
public void setFragment(Fragment fragment, int container) {
getSupportFragmentManager().beginTransaction().add(container, fragment).addToBackStack(fragment.getClass().getName()).commit();
}
public void popAllFragments() {
// TODO Auto-generated method stub
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
Please add following code when you start first fragment :
popAllFragments();
Fragment_subjects f1 =new Fragment_subjects();
setFragment(f1,R.id.main_framelayout_small_contain);
And add following code when you start second framgnet :
Fragment_season f2 =new Fragment_season();
setFragment(f1,R.id.main_framelayout_small_contain);
Then after finally on your back button write following code :
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
getActivity().onBackPressed();
Try this may be work for you
You need to replace the current fragment with a new fragment.
This can be done by following code.
Fragment fragmentSeason = new Fragment_season();
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.main_framelayout_small_contain, fragmentSeason);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
On back press, you would get your first fragment.
There is some implementations issue in method set_fragment_subject
If you have declare set_fragment_subject method in Fragment_1 then your code in method should be like this,
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft= fragmentManager.beginTransaction();
final Fragment_season f2 = new Fragment_season();
ft.add(R.id.main_framelayout_small_contain,f2);
ft.hide(this);// Here this means the current fragment because this method is declared in Fragment_1
ft.addToBackStack(null);
ft.commit();
Hi I have 5 fragments Now first time when I go to Activity of that fragments then default First fragment is called,then on first Fragment there is a button by clicking that button I go to the second fragment,similarly in Second fragment There is a button and clicking that button I go to the third fragment and so on.
Now My Question is that Current I am on Fifth fragment ,Now I want to go fifth fragment to second fragment,what should I do for this?
Can any one please tell me?
You can pop the fragment by name. While adding fragments to the back stack, just give them a name.
fragmentTransaction.addToBackStack("frag2");
Then in fragment5, pop the back stack using the name ie.. frag2 and include POP_BACK_STACK_INCLUSIVE
someButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = getActivity()
.getSupportFragmentManager();
fm.popBackStack ("frag2", FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
});
Here is the method to add and replace fragment.
public void addReplaceFragment(Fragment fragment, int addOrReplace) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
switch (addOrReplace) {
case addFragment:
transaction.add(R.id.frame_containerforsearchable, fragment);
transaction.commit();
break;
case replaceFragment:
transaction.replace(R.id.frame_containerforsearchable, fragment);
transaction.commit();
break;
default:
break;
}
}
call of fragment is..
addReplaceFragment(currencyFragmentWithSearch, replaceFragment);
replaceFragment integer variable
currencyFragmentWithSearch Fragment instance
You can always do this :)
getActivity().getSupportFragmentManager().replace(R.id.yourFrameLayout,new Fragment2(),"FRAG2");
OR
Fragment fragment = getActivity().getSupportFragmentManager().findFragmentByTag("FRAG2");
getActivity().getSupportFragmentManager().replace(R.id.yourFrameLayout,,"FRAG2");
Try this code:
Fragment fragment = new SecondFragmentName();
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
just small correction to mudit_sen code. It is working, only if you add .beginTransaction. Thank you.
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayoutId,new FragmentName()).commit();
I am developing a simple android app only for tablets and using android 4.0. My application have the main screen like as follow:
Oncreate() of Main Activity I am adding Fragment A in the main.xml using following code:
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment imageFragment = new ImageFragment();
ft.replace(R.id.fragment_container, imageFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();
This fragment A just have only a Image view which is clickable. Now I want that when user click on Image view then another fragment (Fragment B) should call and it replace the image view. The Fragment B have a VideoView which play the video.
So My second screen should be like as follow:
My problem is I am not gettting "How to call second fragment from the first one with in main screen activity?"
I can use different activities but I do not want to do so and just want to run this using fragments.
Please guide me.
This is the simplest way:
1) Inside YourActivitycreate a method:
public void goToSecondFragment(){}
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment secondFragment = new SecondFragment();
ft.replace(R.id.fragment_container, secondFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();
}
2) In your first fragment, when you want to replace it, call:
YourActivity activity = (YourActivity) getActivity();
activity.goToSecondFragment();
You can do the same using below:
Adding a fragment with maintaining a back stack
FragmentManager supportFragmentManager = getSupportFragmentManager();
supportFragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
}
});
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.addToBackStack("fragmentTag");
fragmentTransaction.replace(R.id.slate, fragment, "fragmentTag");
fragmentTransaction.commit();
And Replacing a fragment
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.replace(R.id.slate, fragment, "fragmentTag");
fragmentTransaction.commit();
Should work for you.