I have trouble understanding in FragmentTransaction.replace(id, fragment, 'string') what does .replace actually
I read somewhere that it will replace the content of view id with fragment but in my
public class MainActivity extends
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.fragment_container) !=null) {
if(savedInstanceState!=null){
return ;
}
ArticleFragment first_fragment = new ArticleFragment();
HeadlineFragment second_fragment = new HeadlineFragment();
first_fragment.setArguments(getIntent().getExtras());
second_fragment.setArguments(getIntent().getExtras());
FragmentTransaction manager=getSupportFragmentManager().beginTransaction();
manager.add(R.id.fragment_container, first_fragment,"first");
manager.add(R.id.fragment_container, second_fragment,"second");
manager.commit();
}
abc newFragment = new abc();
Bundle args = new Bundle();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment,"second");
transaction.addToBackStack(null);
transaction.commit();
}
}
it only replaces the first fragment that i added to Transaction, i.e. first_fragment.
And how do i replace a specific fragment?
The issue seems to be with R.id.fragment_container. You should have a different first argument on the line below in order to replace a fragment that is not your "first" fragment:
manager.add(R.id.fragment_container, second_fragment,"second");
Related
I am developing an app in which I have used bottom navigation bar so for that I had to use fragments. In my fragments, I implemented Recycler view. So My question is when I click on an item of recycler view, how can I navigate to another fragment (which is in a different item of the bottom navigation bar) and how can I transfer the data between two fragments. Please Help.
during onClick() pass data through bundle
like that
FragmentManager mFragmentManager;
FragmentTransaction mFragmentTransaction;
Bundle bundleobj = new Bundle();
bundleobj.putCharSequence("key", data);
Fragment2 fragobj = new Fragment2();
fragobj.setArguments(bundleobj);
mFragmentTransaction.addToBackStack(null);
mFragmentTransaction.replace(R.id.containerView, fragobj).commit();
In Fragment2 class:
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle =getArguments();
if(null!=bundle) {
myData=bundle.getCharSequence("key");
}
}
In first Fragment..
Fragment fragment = new EditExamFragment();
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
Bundle bundle = new Bundle();
bundle.putString("branch_id", mDataset.get(position).getiBranchId());
bundle.putString("exam_id",mDataset.get(position).getiExamId());
fragment.setArguments(bundle);
In Second Fragment for fetching values try below code;
String branch_id, exam_id ;
final Bundle bundle = this.getArguments();
if (bundle != null) {
branch_id = bundle.getString("branch_id");
exam_id = bundle.getString("exam_id");
}
Add below code after event listener in fragment1
SecondFragmentName secondFragmentName = new SecondFragmentName();
Bundle args = new Bundle();
args.putString("key", "value");
secondFragmentName.setArguments(args);
getFragmentManager().beginTransaction().replace(R.id.content_frame, secondFragmentName).addToBackStack("Some string").commit();
To get value in Fragment2
String message = getArguments().getString("key");
I am making a simple demo project using Fragments, in which i am calling SecondFragment from FirstFragment on button click.
And i called SecondFragment without any issue, but i getting view of both the Fragments SecondFragment and FirstFragment
So where i am doing mistake ?
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new FirstFragment()).commit();
}
}
public static class FirstFragment extends Fragment {
Button buttonCallSecondFragment;
public FirstFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_first, container,
false);
buttonCallSecondFragment = (Button) rootView.findViewById(R.id.button1);
buttonCallSecondFragment.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentManager fm = getFragmentManager();
SecondFragment fragment = new SecondFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.container, fragment);
ft.commit();
}
});
return rootView;
}
}
public static class SecondFragment extends Fragment {
public SecondFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_second, container,
false);
return rootView;
}
}
}
You need to remove the first fragment, you can do that either by usingreplace or first calling remove then add
To be able to press the back button add the transaction to the back stack,you do that by calling addToBackStack(tag) on your fragment manager. Tag may be null.
You are adding fragment on already displaying fragment in your android app.
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.container, fragment);
ft.commit();
Do not add fragment but replace fragment when already one fragment is loaded on activity.
So for implementing that :
Please add your code in OnCreate() and add below code to your click listener :
FragmentManager fm = getFragmentManager();
SecondFragment fragment = new SecondFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
Thank you.!!
if you want to replace fragment you should call replace in place of add :
buttonCallSecondFragment = (Button) rootView.findViewById(R.id.button1);
buttonCallSecondFragment.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentManager fm = getFragmentManager();
SecondFragment fragment = new SecondFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container, fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();
}
});
You are adding the fragment so it will come on top of another fragment give background color to rootview of scecond fragment
you can also load that as Nested fragment
public void addFragB() {
FragmentManager childFragMan = getChildFragmentManager();
FragmentTransaction childFragTrans = childFragMan.beginTransaction();
SecondFragment 2ndfrag = new SecondFragment();
childFragTrans.add(R.id.fragA_LinearLayout, 2ndfrag);
//childFragTrans.addToBackStack("");
childFragTrans.commit();
}
No, you cannot communicate between fragments like this. You need to communicate between fragments via the container activity.
I suggest, you make a navigation method in your activity and switch/call between fragments from there.
Below is a small snippet:
In your container activity:
Fragment fragment;
public void navigateTo(Fragment newFragment,boolean addToBackStack) {
this.fragment = newFragment;
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.fragment_container, newFragment);
if(addToBackStack)
ft.addToBackStack(fragment.getClass().getSimpleName());
ft.commit();
}
If you are going from Fragment1 to Fragment2 then in your Fragment1 do the following:
((YourContainerActivity) getActivity()).navigateTo(new Fragment2(),false); //if you want to add to back stack make 2nd argument true.
private void selectItem(int position) {
selectedPosition = position;
// update the main content by replacing fragments
fragment = null;
fragmentStack = new Stack<Fragment>();
switch (position) {
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
}
//redirect the screen
if (fragment != null) {
fragmentManager = getSupportFragmentManager();
redirectScreen(fragment);
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(title[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
}
I am trying to pass an object Fragment -> Activity -> Fragment.
My 2nd Fragment says my object is null when getting arguments:
Fragment A: (Sending Object, communicator is interface to Main Activity)
meetsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Meet meet = new Meet();
meet = meetList.get(position); // meet is not null here
communicator.changeToolbarTitle(meet.getName());
****** Sends Meet object to main activity ********
communicator.sendMeetToMeetProfile(meet);
}
});
Main Activity:
#Override
public void sendMeetToMeetProfile(Meet meet) {
MeetAthletesListContainer meetAthletesListContainer = new MeetAthletesListContainer();
***** Fragment is not replaced just called *******
MeetAthletesMales meetAthletesMales = new MeetAthletesMales();
MeetAthletesFemales meetAthletesFemales = new MeetAthletesFemales();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Bundle bundleMales = new Bundle();
bundleMales.putParcelable("meetAthletesMales", meet);
meetAthletesMales.setArguments(bundleMales);
Bundle bundleFemales = new Bundle();
bundleFemales.putParcelable("meetAthletesFemales", meet);
meetAthletesFemales.setArguments(bundleFemales);
******* Replaces current fragment with container that contains above (2) fragments *******
transaction.replace(R.id.frameLayout, meetAthletesListContainer, "meetAthletesListContainer");
transaction.addToBackStack(null);
transaction.commit();
}
Fragment B: (Fragment is contained inside another fragment)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_meet_athletes_males, container, false);
Log.e("", "Fragment onCreateView Called!");
initializeVar();
*****Says this meet object is null*****
meet = getArguments().getParcelable("meetAthletesMales");
}
I am replacing a fragment with another but passing the object to a fragment which is inside another fragment(meet_container_fragment). So my object is being sent directly to the fragment. I got this working in another instance where I actually replace the fragment but I want to replace the FRAGMENT CONTAINER, not the actual fragment B
Try this
MeetAthletesListContainer meetAthletesListContainer = new MeetAthletesListContainer();
***** Fragment is not replaced just called *******
MeetAthletesMales meetAthletesMales = new MeetAthletesMales();
MeetAthletesFemales meetAthletesFemales = new MeetAthletesFemales();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Bundle bundle = new Bundle();
bundle.putParcelable("meetAthletesMales", meet);
bundle.putParcelable("meetAthletesFemales", meet);
meetAthletesFemales.setArguments(bundle);
******* Replaces current fragment with container that contains above (2) fragments *******
transaction.replace(R.id.frameLayout, meetAthletesListContainer, "meetAthletesListContainer");
transaction.addToBackStack(null);
transaction.commit();
Try this,
main activity
FragmentB fragmentb = FragmentB.newInstance(appContext,meet);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.contentContainer, fragmentb , tag);
Fragment B
public static FragmentB newInstance(AppContext appContext, Meet meet) {
FragmentB fragment = new FragmentB();
Bundle args = new Bundle();
args.putSerializable(ARG_APP_CONTEXT, appContext);
args.putString(ARG_MEET_NAME, meet.name);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
appContext = (AppContext) getArguments().get(ARG_APP_CONTEXT);
name= getArguments().getString(ARG_MEET_NAME);
}
}
also make Meet implements Serializable
I was trying out android fragments, and i could not understand this; please help
public class MainActivity extends FragmentActivity {
private static final String TAG = "MyActivity";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.fragment_container) !=null) {
if(savedInstanceState!=null){
return ;
}
ArticleFragment first_fragment = new ArticleFragment();
HeadlineFragment second_fragment = new HeadlineFragment();
first_fragment.setArguments(getIntent().getExtras());
second_fragment.setArguments(getIntent().getExtras());
FragmentTransaction manager=getSupportFragmentManager().beginTransaction();
manager.add(R.id.fragment_container, first_fragment,"first");
manager.add(R.id.yo, second_fragment,"second");
manager.commit();
}
}
now i want to remove second_fragment at a button press and replace it with another. So i tried this
if(getSupportFragmentManager().findFragmentByTag("second")!=null) {
Log.d(TAG,"found");
abc newFragment = new abc();
Bundle args = new Bundle();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.remove(getSupportFragmentManager().findFragmentByTag("second"));
transaction.add(R.id.fragment_container,newFragment,"third");
transaction.addToBackStack(null);
transaction.commit();
}
but when i press that button again and again, the if condition passes.
What is wrong here?
Don't Do removing and adding. Simply Replace second fragment with the new one. You will be done.
I've created a fragment, Fragment01, that extends MapFragment. Problem is that because it doesn't extend Fragment anymore, now the onSelectFragment part of my MainActivity doesn't work anymore. What do I need to change in my MainActivity to get it to work like before? The error I'm getting is on the line newFragment = new Fragment01(); where it says Type mismatch: cannot convert from Fragment01 to Fragment. Being a noob, I simply tried with newMapFragment = new Fragment01(); but that didn't do it.
MainActivity
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
StartFragment startfragment = new StartFragment();
transaction.add(R.id.fragment_placeholder, startfragment);
transaction.commit();
}
public void onSelectFragment(View view){
Fragment newFragment;
if (view == findViewById(R.id.btnstartfragment)) {
newFragment = new StartFragment();
} else if (view == findViewById(R.id.btnfragment01)) {
newFragment = new Fragment01();
} else if (view == findViewById(R.id.btnfragment02)) {
newFragment = new Fragment02();
} else {
newFragment = new StartFragment();
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_placeholder, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
It may be error with different Fragment hierarchies: from support library and platform.
Check your imports and hierarchy of MapFragment.
These are two different types:
android.support.v4.app.Fragment
android.app.Fragment