My android application have BottomNavigationBar. It contains 5 fragments. One of its fragment contain nested fragment which is mutiple step process.
first nested fragment contain next button.Second nested fragment contain previous and next button.Third nested fragment contain previous and submit button. Each fragment have different EditText.
After adding the values in first fragment, when i click next button it goes to second fragment. In second fragment when i click previous button it goes to first fragment again and same process applies to second and third fragment
My questions is:
1)When previous button in second fragment is clicked, i want all the values of EditText in first fragment as it is and when again next button of first fragment is clicked, i want all the values of EditText in second fragment as it is. Is there any way to do this?
2)I want all the EditText values of all nested fragments when user clicked on submit button in third fragment.How to do that?
Yes,
This can be achieved using two ways,
1) Fragment savedInstanceState
https://stackoverflow.com/a/17135346/7316675
2) Keep you values stored at some activity or application level, and access it on resume of fragment screen
You could use a Bundle to store the values and then restore them when you restore the fragment. You could either do this in onStop() (recommended) or onPause().
Private static final String KEY_ADDRESS = "ADDRESS" ;
#Override
Public void onstop(){
Bundles state = new Bundle ();
String address = etv1.getText().toString();
// Get more strings from the etvs
state.putString(KEY_ADDRESS, address);
// Store more strings into the bundle
setInitialSavedState(state)
}
To restore the values you use either the saved instance state the system passed to onCreate() , or pass the bundle to a self created public bundle in onCreate() and access in onResume() like so:
String address = bundle.getString(KEY_ADDRESS);
As for the results being passed you could communicate the bundles to their parent activity whenever the next or previous button is pressed and do with it as you please when submit is pressed. Learn more on How to do that from the docs or this answer on how to do that
Solution of my first question.
I have used popBackStack() method of FragmentManager. Using this i can go back to the previous fragment of stack.I have added this code in OnClickListener of previous button
FragmentManager fm = getActivity().getSupportFragmentManager();
if(fm.getBackStackEntryCount()!=0){
fm.popBackStack();
}
Solution of my second question:
use method setArguments() to set the values and getArguments() to get the values
Related
I am using ScreenSlidePagerAdapter, ViewPager and PagerAdapter
I have three fragments and every fragment contains three to four editText fields.
Fragment 1: personalInfo
Fragment 2: contactInfo
Fragment 3: workInfo
WorkInfo also contain Clear Button to clear all editText data form all three Fragmnets.
When user enter value in personalInfo then contactInfo and at last go to WorkInfo.
Now at click of Clear button I want to clear all editText data.
I tried findViewById() but I could not get reference of editText from Fragment 1 and Fragment 2.
If anyone has a solution then help me.
Do something like this:
Make a boolean variable in your class initialized to false. When someone clicks on clear, change the value of that boolean to true. And in onstart() check this variable before showing data in edittext.
Use an interface to communicate between fragments. You could read more about this from the Android Developer Docs.
https://developer.android.com/training/basics/fragments/communicating.html
In resume, from your Fragment 3 you must call a method from your interface that must be implemetend by your activity. Then your activity must notify Fragment 1 and Fragment 2 to update their views.
Hope this help you.
I am trying to build a delivery app. I have a list of products to choose from. After the user selects a product then he is lead to a series of stages to define extras and options of a certain product.
List of products:
Then, Lets say someone clicks on one of the products, we go to the controller FragmentActivity:
The subtotal at top and the button at the bottom of the page belongs to the fragment activity. Then I place a group of radio buttons at the center layout. Everything is fine till now. Click on the button leads for the replacement of the fragment:
Everything is beautiful until now. I can access the buttons and the subtotal through the fragments. However, if I press the back button on the device it leads me back to the list of products and not to the previous fragment. Even if I manage to go back to the previous fragment it would lose the radiobutton selection as well.
Then the next fragment is a calculation of the products and its extras:
When I press the button, I just use finish() in the fragment and it leads me back to the list of products which is my desired result. However, I need to know that I am coming from there in the list of products so I can add that product to the shopping cart that is being built for the delivery order.
I am really new in using fragments, but I can pass arguments just fine. What I am struggling is to control the navigation of the fragments through the FragmentActivity that controls the fragments. Also, I am struggling to keep the states of the fragments (remembering user input). At last, I need to go back to the list of products with a result of that item that was being constructed so I can add it to the shopping cart.
Am I going to the right direction? How can I implement these features(navigation, fragment state, returning to previous activity with some data since I just use finish()), Many thanks guys!
You can navigate between the fragments just by adding them into the back stack like following:
// Works with either the framework FragmentManager or the
// support package FragmentManager (getSupportFragmentManager).
getSupportFragmentManager().beginTransaction()
.add(detailFragment, "detail")
// Add this transaction to the back stack
.addToBackStack()
.commit();
That way, when you will click the back button, it wont load the previous activity from the stack but the previous fragment that has been added in the backstack. You can find more details here: http://developer.android.com/training/implementing-navigation/temporal.html
Use the onSaveInstanceState(Bundle savedInstanceState) and the onActivityCreated(Bundle savedInstanceState) on every fragment that you want to save and retrieve data. And then do the following:
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
//Restore the fragment's state here
String yourString = savedInstanceState.getString("key");
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
//save whatever you want into the bundle
savedInstanceState.putString("key", "your_value");
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
You can save whatever you want into the Bundle. From Strings to Parcelables and Serializables. More info here: http://developer.android.com/reference/android/os/Bundle.html
my android app main activity contains two fragments.The main activity also contain two buttons-save and cancel.The fragments contain EditTexts and Spinners.i want to take data from these EditTexts and Spinner upon Save button click event(Event occur in parent activity).Is it Possible?
You are able to get the current fragment by doing getFragmentManager().findFragmentById(R.id.fragmentId) that will return the current fragment. You can then check its type by calling getClass() or by checking its instance as such if(getFragmentManager().findFragmentById(R.id.fragmentId) instanceof MyFragment){
//Code goes here
} You can then type cast it if it is the correct class and call whatever methods you want
MyFragment fragment=(MyFragment)getFragmentManager().findFragmentById(R.id.fragmentId);
fragment.getSomeData();
I have a fragment and an activity.there are some fields and an button in fragment.When i click an button in fragment then i want to go to an activity.In that activity i have another button.when i click on that button i want to return from the present activity to the previous fragment.Every thing works fine.what i need is i want to recreate the fragment when i return to the fragment from the activity..i.e,for example in the fragment if i enter anything in the edit_text before passing to the activity, which is also presented when i returned from the activity.(the fragment is same as how i left from fragment) which is i don't want .i want a fresh page.i want to recreate a fragment when i returned from activity ..i need to select fields newly..can any one suggest any help..thanks in advance..
Try to use main FragmentActivity and Fragments and organize transactions between fragments. I didn't meet examples with Activity and Fragment in one Addlication.
So I am trying to get some experience with Fragments, but I'm finding some roadblocks.
My current situation is as follows.
I have an activity that displays a List whose content is determined by Extra Intent parameters sent from the 'calling' activity.
This List activity uses ListFragment declared in the XML like so:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" android:background="#color/black">
<fragment class="com.pixlworks.NLC.DirectoryBrowse$ListingFragment"
android:id="#+id/listing"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Currently I get the parameter that indicates the type of content directly in the Fragment by accessing the Extra data of the Activity Intent (or saved Bundle if available):
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null)
mListingType = savedInstanceState.getString(Utils.DIRECTORY_TYPE_STORE_KEY);
else
mListingType = getActivity().getIntent().getStringExtra(Utils.DIRECTORY_TYPE_STORE_KEY);
// get content by type, create and set the adapter
}
Now part of my problem is that I am not sure this is the right way to 'pass' that parameter from the Activity to the Fragment.
On top of that, I am getting issues with this setup when using the Action Bar's UP Navigation. When I click on an item in this List Activity it goes to another activity showing the details of the selected item. From this detail activity:
If I use the back button, the List Activity is brought back from the stack as usual and everything works fine.
If I use the ActionBar's UP (despite following steps here), it would seem that a new instance is created instead of using the one in the stack and this new instance obviously is not getting the Extra parameter in the Intent. Since I am expecting the value to exist in the saved Bundle or in the Intent, my app crashes in this situation.
So to boil things down, I am not sure which of these to follow and how to make them work properly with 'UP' navigation:
A) Hold the 'type' parameter in a field in the Activity and save it in the Activity's Bundle onSaveInstanceState. In which case I am not sure how to then pass the value to the Fragment. In this case I would just need to make sure that UP calls the existing instance of the Activity List
B) Continue with my current setup of saving the value in the Fragment instead of the Activity, but again, how to handle the UP navigation correctly?
I know it is kind of multiple things I am asking here at the same time, but they are all connected, so I hope that I can get some help on this.
Thanks for any help in advance!
The UP navigation makes more sense to be used within the same activity level. That is the intention of the codes that you followed in the developers page. Because you started a new activity, if you want to return to previous activity like the back button you will need to call finish() to destroy the details activity first.
As for passing data from activity to fragment, when you create a new instance of fragment, you can pass the data to it as bundle, for example:
// in fragment class
public static MyFragment newInstance(Bundle arg) {
MyFragment f = new MyFragment();
f.setArguments(arg);
return f;
}
When you create a new fragment, you can call:
// in activity
Bundle arg = new Bundle();
int info = ...;
arg.putInt("INFO",info);
...
MyFragment mFragment = MyFragment.newInstance(arg);
Finally, to get the data in fragment:
int info = getArguments().getInt("INFO");
...
Instead of directly calling MyFragment mFragment = new MyFragment() to instantiate the fragment, you should use a static method to instantiate it. This is to prevent some crashes which might happen if you rotate the screen and the framework complains that it couldn't find a public empty constructor.
UPDATE
To answer your questions:
1) Say you start from activity A -> activity B. Then in activity B you press the up button. By logic of use, the up button will not bring you back to activity A, because its intention is to navigate one level up,but still inside, activity B. To return to activity A, you need to call finish() to destroy activity B first.
2) If your fragment is created in xml, you still can set arguments. In your xml, you set an id for the fragment android:id="#+id/fragment_id", then
// in activity
FragmentManager fm = getSupportFragmentManager(); // or getFragmentManager() if you don't have backward compatibility
MyFragment mFragment = fm.findFragmentById(R.id.fragment_id);
Bundle arg = new Bundle();
// put data blah blah
mFragment.setArguments(arg);
Just make sure you set the arguments before you use the fragment.
Simply said, intent is used when you pass data between calling activities; bundle is used when you want to pass data from activity to fragment.