I created a navigation drawer. Now,navigation drawer requires all fragments. I want to send some information and move to this fragment which contains drawer from an activity. How do I implement this ? I am using Intent(activityclass.this,fragment.class) for navigation and putExtra for sending data. But the app crashes.
Fragments are not loaded using Intent. You need to use FragmentManager:
Fragment fragment = new MyFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.container,fragment).commit();
your approach needs some modification i would like to refer the below links for better ways
official tutorial
Some good practises for your app communication
Related
framentA calls fragmentB via an mother activity. FragmentA is no longer in memory. FragmentB calls fragmentA(go back to previous screen). FragmentB has some data to share with FragmentA. But, how?
here is what I tried:
static variable - it worked, but a bad habit, I can not use it
viewModel - each fragment creates it's OWN instance of view model. Therefore the 2 instances of the viewModel will not work.
DB - not a good pattern. Therefore I cant use it.
I think what you need is to store the fragments in Fragment Manager, when you do that you are basically trying to maintain a back stack of your fragments:
FragmentManager fragmentManager = getSupportFragmentManager();
//or FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.add(FragmentToBeAdded, "textRelatedtoFragment")
.addToBackStack(null)
.commit();
Adding to the backstack helps in saving the state of the fragment.
My suggestion would be:
For Fragment Navigation use: https://developer.android.com/guide/navigation/navigation-getting-started
It will greatly simplify your in-app navigation.
For passing parameters between Fragments/Activities:
First solution is to use ViewModel with scoping of Activity using by activityViewModels(). Read More here: https://developer.android.com/jetpack/guide This will give you an indirect way of passing arguments.
Use SafeArgs (part of Navigation component) to directly pass needed data.
More information can be found here: https://developer.android.com/guide/navigation/navigation-getting-started#ensure_type-safety_by_using_safe_args
I'm learning about fragments I have some doubts. Consider following code:
FragmentManager fm = getFragmentManager();
Fragment MyFragment = new Fragment();
fm.beginTransaction().replace(R.id.my_container, MyFragment).addToBackStack(null).commit();
My question is:
what exactly does replace do?
What happens if I create many fragments this way (to replace previous ones in a container).
Can it in any way be bad for memory usage?
Is it considerably better just to change fragment's content?
Replace removes all the fragments that are in the container and adds the new fragment to the container. (if there isn't a fragment in the container then it just adds the new one).
If you create many fragments this way then every transaction is saved to the backstack so you can reverse the transaction by pressing the back button.
The only thing you can do is to create a variable fragmentTransaction and use the fm.beginTransaction() only once and not every time you want to replace the fragment in the container.
I don't think so, fragments should be modular and reusable.
You can read more here:
https://developer.android.com/guide/components/fragments.html
it simple put another "layer" on container.
appcrash
yes
No, fragment is the easiest way.
Using fragment & backstack tag to reference to a Fragment if you want to call fragment again and process Back button.
fm.beginTransaction().replace(R.id.my_container, MyFragment, "FRAGMENT_TAG").addToBackStack("FRAGMENT_BACKSTACK_TAG").commit();
I have an Activity called Mytaskonclick extends Activity and a Fragment called SentTaskFragment extends Fragment. I want to go from Mytaskonclick to SentTaskFragment on click of a button. I tried using the code
Intent ii=new Intent(Mytaskonclick.this,SentTaskFragment.class);
startActivity(ii);
But this code doesn't work. Can anyone suggest me how to do it?
Fragments does not work like this.You need to put a place holder in your activity, say FrameLayout for example and, inside on click, you get the fragment and attach it inside this placeholder. I suggest you read the Fragment Tutorial Here. It contains all what you need to know and extremely useful for you.
When you want to switch to a Fragment them you have to do that through FragmentManager. Pass that thae Fragment object into beginTransaction() method of FragmentManager along with the container layout which will hold the Fragment as below...
SentTaskFragment fragment = new SentTaskFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().add(R.id.frame_container, fragment).commit();
You can see some tutorial from below link...
Android Developer-Fragment
Multi-pane development in Android with Fragments - Tutorial
Android Fragments
Android Fragments Example
There're two parts to this question.
Suppose we have an Activity and then two fragments: a ListFragment and a Fragment (which will be shown when you click an item from the ListFragment).
Part 1
Where should I close the fragment? By this I mean what would be considered good from a design point of view. I see two options: one declaring an interface in the fragment and having the activity implementing it, let's call it closeFragment(). This would be a way to communicate from the fragment to the activity like shown in the Dev Site. The other one is probably quite simple and is calling getActivity().getSupportFragmentManager() and using the manager to close it.
Part 2
I know how to create a fragment and replace it since it's on the Dev site but I have doubts about closing one. How should I actually close it? Is something like the following code correct? Suppose that the fragment was added to the BackStack.
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
getSupportFragmentManager().popBackStack();
transaction.remove(this);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
transaction.commit();
Thank you very much.
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.remove(this);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
ft.commit();
I would prefer having a dumb fragment , which don't know anything about where it is being used , so that you could use it on any activity you wish , and it would have the precise goal you've set for it . Of course , you can do whatever you wish .
This looks like closing it , but I would prefer replacing it instead . You can also always return to the fragment as long as you have a reference to it .
This is a design question, rather than a technical one.
General case: I want an UI event in a Fragment to make Activity-wide changes.
Specific case: I have two fragments, hosted in the same activity. When the user clicks a button in one of those fragments, I want it to be replaced by the other.
I don't want, however, my Fragments touching my activity. I may want to change the behavior later (maybe, in a bigger screen, show both fragments instead of replacing the first), and I don't want my Fragment code to have that logic.
What I did was implement a Listener class in my fragments, that reports events back to the Activity. This way, if I want to use another Activity class with different display behavior, I can just change the listener and leave the Fragment code untouched.
Is this a good way to go about it? Is there a standard good practice, or a better design pattern?
Using listeners is the recommended way of communicating between Fragment and your activity.
See this Android documentatin section for infromation. Long story short they just implement a listener interface by the Activity class and cast getActivity() result in a fragment to a listener.
From my personal experience this is very convenient because lets you to:
Easilly switch underlying activity (e.g. you host entire fragment in a wrapper activity for compatibility in pre-3.0 and host this fragment along with others in 11+)
Easilly control if the wrapper activity supports callbacks or not. Just check is it does implement the listener and do your app specific actions if it doesn't.
You are right on about using a Listener. This is something I also had to deal with in a project at work. The best way to handle it is to make the Fragment stand-alone in nature. Anything wishing to interact with the Fragment should use its public API and/or set listeners for specific events. If you are familiar with Design Patterns, this is the Observer pattern. The events can be general or specific as well as contain data or no data.
As an example of my project, I had two Fragments. A ListFragment and an InfoFragment that displayed the selected ListItem. The ListFragment already has a Listener interface for my Activity to hook into, but the InfoFragment does not since its your basic Fragment. I added a Listener interface to the InfoFragment that would be notified when the Fragment wanted to close. For the Fragment, this could be by a button press, or specific action occured, but as far as my Activity is concerned, when the Event is triggered, it would close up the Fragment view.
Don't be afraid to use a lot of Listeners for Fragments, but also try to group them by a specific action using data parameters to individualize them. Hope this helps!
A technical answer for:
I have two fragments, hosted in the same activity. When the user clicks a button in one of those fragments, I want it to be replaced by the other.
FragmentTransaction ft = this.getFragmentManager().beginTransaction();
Fragment mFragment = Fragment.instantiate(this.Activity(), Fragment2.class.getName());
ft.replace(android.R.id.content, mFragment);
ft.commit();
public class Example_3_Mainfile extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.example_3_mainfile);
Fragment fr ;//make class that extend to thefragment
fr = new Act_2_1();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
//id get of fragment tag from xml file there decelar
fragmentTransaction.commit();
}
}