I have 2 Fragments for an activity. e.g. FragmentA and FragmentB. I have a public method MethodA in FragmentA. Now I want to use MethodA in FragmentB of FragmentA.
One of the way to do is Create Interface and implement your activity with that interface. Now initilize that interface in FragmentB and on click of something you have to call the method of interface wherever you want to call method of FragmentB. Now in your activity callback method just call the method of FragmentB with the help of object
First you have to get list of all fragment and then child fragment then check your fragment instance.
for (Fragment fragment : getSupportFragmentManager().getFragments())
{
for (Fragment fragment1 : fragment.getFragmentManager().getFragments())
{
if (fragment1 instanceof Shoppingcart)
{
FragmentA mFragmentA = ((FragmentA) fragment1);
mFragmentA.A();
}
}
}
Related
I replace Fragment-A with Fragment-B, and on calling popbackstack() in Fragment-B i will redirect back to Fragment-A. So I wanted to call a method that will update the list.
One more importance difference between add and replace is: replace removes the existing fragment and adds a new fragment. This means when you press back button the fragment that got replaced will be created with its onCreateView being invoked. Whereas add retains the existing fragments and adds a new fragment that means existing fragment will be active and they wont be in 'paused' state hence when a back button is pressed onCreateView is not called for the existing fragment(the fragment which was there before new fragment was added). In terms of fragment's life cycle events onPause, onResume, onCreateView and other life cycle events will be invoked in case of replace but they wont be invoked in case of add.
In Short for your use case, you need to use add and if you don't want the fragment views to overlap then you might replace the Fragment B view background color with a solid color instead of transparent.
When you add your fragment, you also have to add it to your fragment's backstack.
FragmentTransaction ft = getSupportFragmentManager.beginTransaction();
ft.replace(R.id.content, fragment, backStateName);
ft.addToBackStack(backStateName);
ft.commit();
(here R.id.content is your fragment container in your activity)
Then you have to override onBackPressed method in your activity that contains your fragments.
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
}
}
if you want to customize your onBackPressed then you can check for your currently visible fragment in your activity and create a callback for performing action for that particular fragment. example -
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content);
if (fragment instanceof FragmentB) {
((FragmentB) fragment).onBackPressed();
// getSupportFragmentManager().popBackStack();
}
}
now you can add getSupportFragmentManager().popBackStack(); in your Fragment's onBackPressed() method.
What Structure I am having:
I Have a Activity called MainActivity.java
Inside MainActivity.java there is ParentFragment.java
Now inside ParentFragment.java there is ChildFragment.Java
Now inside ChildFragment.Java there is a adapter for it
ChildAdapter.java
Inside ChildAdapter.java the is a method called MyMethod()
Now How to access the MyMethod() in MainActivity.java
Here is the solution
1.Find ParentFragment in MainActivity by its TAG
2.And from the ParentFragemnt instance find ChildFragment with its TAG using getChildSupportManager()
3.And now create ChildAdapter variable global in ChildFragment and make it public
4.And from ChildFragment instance access the ChildAdapter
5.And than you can access MyMethod() from ChildAdapter variable
I usually use this method in the Activity which has to replace the Fragments:
/**
* This method is used to load the fragment once an item gets selected
*
* #param fragment This is the chosen fragment you want to select
*/
public void loadFragmentActivityFrameLayout(final Fragment fragment) {
// create a transaction for transition here
final FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
// put the fragment in place
transaction.replace(
R.id.frameLayoutId,
fragment,
fragment.getClass().getSimpleName());
// this is the part that will cause a fragment to be added to back stack,
// this way we can return to it at any time using this tag
if(fragment instanceof Fragment1){
transaction.addToBackStack(Fragmen1.class.getSimpleName());
}else if(fragment instanceof Fragment2){
transaction.addToBackStack(Fragment2.class.getSimpleName());
}else if(fragment instance of Fragment3){
transaction.addToBackStack(Fragment3.class.getSimpleName());
}else if(fragment instanceof Fragment4){
transaction.addToBackStack(Fragment4.class.getSimpleName());
}
transaction.commit();
}
And then you can retrieve an instance of each Fragment in that Activity, like this:
Fragment1 frag1 =
(Fragment1)getSupportFragmentManager()
.findFragmentByTag(Fragment1.class.getSimpleName());
Fragment2 frag2 =
(Fragment2)getSupportFragmentManager()
.findFragmentByTag(Fragment2.class.getSimpleName());
Fragment3 frag3 =
(Fragment3)getSupportFragmentManager()
.findFragmentByTag(Fragment3.class.getSimpleName());
Fragment4 frag4 =
(Fragment4)getSupportFragmentManager()
.findFragmentByTag(Fragment4.class.getSimpleName());
And then, since you got an adapter, make it public in its Fragment, let's say "frag1", don't forget to make "MyMethod()" also public into the adapter :
public CustomAdapter adapter;
And finally you can retrieve any adapter method from the Activity:
frag1.adapter.MyMethod();
Hope I've been clear.
In many websites i see that a fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle - when the activity is paused, so are all fragments in it, and when the activity is destroyed, so are all fragments.
But, it's also written there that we can reuse fragment in different activities - but from above, if we move to another activity, the fragment will be destroyed. What i'm missing, or moreover, can someone give me an example of reuse same fragment in different activities?
I think you're getting confused with the concepts of Fragment implementation and Fragment instance. You can use the same Fragment implementation in different Activity, but for each Activity you need a new Fragment instance. The lifecycle of that instance is what will be directly affected by the host Activity's lifecycle.
Having a Fragment, let's call it FragmentA, and a couple Activity, let's call it ActivityA and ActivityB, you have 3 classes:
public FragmentA extends Fragment {
// All the FragmentA implementation
}
public ActivityA extends Activity {
// All the ActivityA implementation
}
public ActivityB extends Activity {
// All the ActivityB implementation
}
In this case, you could use the implementation of FragmentA in booth ActivityA and ActivityB, but for each case you'll need to create a new instance of FragmentA.
public ActivityA extends Activity {
loadFragmentA() {
FragmentA instanceA = new FragmentA();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, instanceA)
.commit();
}
}
public ActivityB extends Activity {
loadFragmentA() {
FragmentA instanceB = new FragmentA();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, instanceB)
.commit();
}
}
Like this, instanceA would be related to the lifecycle of ActivityA and instanceB would be related to the lifecycle of ActivityB, but booth are instances of FragmentA.
Reusing means that a certain Fragment (FragmentA) isn't tied to a certain Activity (ActivityA), but can be used by different Activities (ActivityB, ActivityC). It doesn't mean that you can pass a Fragment instance between Activities.
You are getting it little wrong. By reuse it means that we can use one fragment(definition) at multiple places rather than the fragment object itself. It doesn't mean that you can pass fragment instance between activities. For new activity, there is a new SupportFragmentManager/Manager. So, you have to create a new instance of the same fragment.
Fragment thus allows you to keep only one piece of code for different screens.
The key here is onAttach(Activity) method of Fragment which is called once the fragment is associated with the parent activity.
You create an instance of a fragment class for any activity you need to use the fragment in and use it in a fragment transaction.
DetailsFragment details = DetailsFragment.newInstance(index);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.details, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
If you want to reuse a fragment, you should conver the activity as a fragment.
You only can reuse a fragment of an existing fragment of the FragmentManager you want to do the transaction (of activity or fragment).
See this post from FragmentManager:
https://developer.android.com/reference/android/app/FragmentManager.html
The fragments are allowed in the BackStack if you call the method addToBackStack at transaction.
I am having a fragment A in which i initialized another fragment say Frgament B. My fragment A is having a listview. On click of that listview i need to call a method of fragment B and update Textview. But as soon as i call this method it flashes following message in Logcat
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
My code is as follows :
public class FragmentA extends Fragment {
// in oncreateview
FragmentB fb=new FragmentB();
// on listview click item i call a method of fragment B
setdata(value); // where value is clicked position
}
// Fragment B is as follows :
public class FragmentB extends Fragment {
// IN ONCRAETEVIEW
initialized textview
return view;
public void setdata(int data)
{
// Updating textview settext method
}
}
Please help
Thanks in advance
Only the fragment B is add into the layout then the View of the fragment B is created. So you should call setdata() after the fragment transaction.
Fragment fragmentB = new Fragment();
getFragmentManager().beginTransaction().add(R.layout.container, fragmentB).commit();
fragmentB.setData(value);
FragmentManager m=getSupportFragmentManager();
FragmentB fb=(FragmentB )m.findFragmentById(R.id.your_fragment_id_from_xmlsetdata);
fb.setdata(value);
try with this code it will definitely works
I have a fragment(this is one tab of my tabhost) "fragA" inside other fragment "fragB" but I need to call one method of "fragB" from "fragA".
when I do from an activity, I do this:
FragB detailsFragment=(FragB)getSupportFragmentManager().findFragmentById(R.id.detailFragment);
detailsFragment.consultaWS(convertIntWebService(categoria),"Pdf");
please, help me
I could finally solve it this way, in fragA:
FragB parentFragment = (FragB) getChildFragmentManager()
.findFragmentByTag("detallesFragBusqueda");
if (parentFragment != null) {
parentFragment.consultaWS("", "AllPdf");
}
Your activity should facilitate all communication between fragments. Just create a method in your Activity that a fragment can call, which will tell another fragment to do something.
If FragA is inside FragB, you can do the same from within your FragA.
FragB parentFragment = (FragB)getActivity().getSupportFragmentManager().findFragmentById(R.id.detailFragment);
parentFragment.fragmentBMethod();
Read this http://developer.android.com/training/basics/fragments/communicating.html.
This document explains that how can you communicate between Activity and Fragment
and also between 2 Fragments
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_main_container);
if (fragment != null) {
((TabLayoutFragment)fragment).tabClickDisable();
}