I would like to check if a fragment was created for the first time so that I can launch a different fragment for introduction before coming to the retained fragment.
Normally for an activity I know I would use a sharedPreference-object to store a boolean value that tells me if this is the first time the user opens the activity, check the preference when the user starts the application, and if it returns true then show the middle screen.
Is the same possible for fragments?
Yes, you can use sharedPrference, but maybe it will be better to check the state when you actually switch to this fragment.
I mean you can decide in activity if to show introduction fragment or regular one before you create the fragment.
Related
I making android app. I have 3 activites:
first(main) activity which is empty and it's like navigation which ask you to add item.
Second activity which is needed for adding item's details and this activity have accept button which leads you to third activity.
Third activity have all data about item and from now on i want my app to make this activity main (default) activity with saving information about it in device memory.
I decided to make it without database because it should be really simple.
Can you help me with making 3rd acitivity main? Maybe there are some tricks.
not clear what you trying to ask. Like if user reached the 3rd activity, in the future if user open the app the app will automatically navigate them to the 3rd activity?
If that's the case, you could save this information in the shared preference, when the app start, the first activity check this value and navigate to the 3rd activity.
Recommend you use a single activity, use fragments for different pages, and use Navigation component to connect them. https://developer.android.com/guide/navigation/navigation-getting-started
I have a single ActionbarActivity with two fragments. I have a menu option (maintained in MainActivity) to open a camera intent and capture a picture. When I return from this event, I want to update the first fragment.
Currently, if I select this menu option while the first fragment is visible, I can update the UI by using a reference to an instance in the MainActivty's onActivityResult(). However, if the second fragment is currently visible, the app crashes. (I am away from Android Studio but will be able to post error message shortly, if necessary.)
How can I - from the MainActivity's onActivtyResult() or elsewhere - ensure that the saved instance of the first fragment is returned to and updated, regardless of which fragment is currently visible when the option was selected? Or is it just as easy to create a new instance of the first fragment? (It would be created with the updated information automatically.)
you can get existing fragments through the FragmentManager from the Activity.
see here how to do this.
I have a ViewPager with a FragmentStatePagerAdapter and the starting page should be somewhere in the middle. But when the user goes to another Activity and then comes back, the page number should be saved, so that he returns to the same page. There is probably an easy way to get this done, but I can't find the solution.
Usually the current page number will be saved, so this is not the point. The problem is that I don't know where to put the code that sets the starting page at first, because when I put it in onCreate, the starting page will be shown even if I come back from a different Activity.
I also tried saving the number in a variable in the onPause method:
this.currentPageNumber = viewPager.getCurrentItem();
But next time when onStart() is called, the variable currentPageNumber is null, so it seems that variables are not saved after onDestroy().
I could use a static variable, but it feels wrong. Is there a better solution?
EDIT: Sorry, I didn't make clear enough, that I want the saved page only be opened, if I come back to this Activity after I launched it. Every time I start the Activity from the launcher, the starting page should be shown and not the saved page.
EDIT 2: The behaviour I want to have is exactly the same as the Google Calendar app has when you open the day or week perspective. If I open this app, the current day will be shown. If I swipe to another day, then open settings, then press back, this other day is still be shown. But if I restart the app, again today will be shown.
After you have initialised your viewpager, use this method :
viewPager.setCurrentItem(int position)
Or this :
viewPager.setCurrentItem(int position, boolean withAnimation)
You can save the last position by using SharedPreference in the onPageSelect() method where you can get the position of each page. You have to implement the OnPageChangeListner in order to have this method.
Edit
Your question wasn't clear :
Sorry, maybe I didn't express my problem well enough. I want the starting page to appear everytime I start my app. But if I enter the activity by the back-button (for example if I opened my settings activity and then go back) the last viewed page should be shown. The solution provided in the link will lead to the safed page everytime I open the app
I don't know why you want to change this, it's a normal behavior, read this.
But if you insist, you can always use setCurrentItem() method in the onResume of your Activity/Fragment, thus the first page will always be shown after your Activity/Fragment gets resumed.
Edit 2
That can still be done by setCurrentItem. In your adapter, try to detect the index of the page of the current day. Create a method that returns that field from outside the adapter. And then after you have initialised your ViewPager,
viewpager = (ViewPager) findViewById(R.id.viewpager);
viewpager.setAdapter(adapter);
setCurrentItem(adapter.getCurrentDayPosition()) // or something like that ...
The method in the adapter :
public int getCurrentDayPosition() {
return this.currentDayPosition // this a field of the adapter.
}
I have the same requirement to show the default page whenever the onCreate of the ViewPager hosting Activity is called and show the current page for all the other cases including the motivating case: when user navigate back from the Activity started from the current page (onCreate won't be called in this case). My solution is based on the time spend between onCreate and onResume.
If the time between onCreate and onResume is shorter then a threshold (I use 1s assuming onCreate could be finished within 1s which we really wanted for the good programming practice), then we believe this is the first time the onStart/onResume is called right after the onCreate, otherwise we believe it is about all the other cases including our motivating case.
Then we only need to set the current timestamp in onCreate and do the time comparison in onResume to make the decision to set the current item of ViewPager to default or current. Note that we need to save the current page number in onPause in SharedPreference.
I am not claiming this idea is perfect but it works fine for me so far. Let me know if you are interested in the implementation and I will post my code upon your request.
i think this solve your problem , because first time you launch your activity there is no instance saved (savedInstanceState) ...
read comments in the post ...Android :Save View Pager State ...
first of, I know that it is not possible to start a fragment via an Intent like you do with activities. However, in my application I would like to have the functionality that I can return from the activity to a fragment on a button click.
How do I do that? Any suggestions?
You can't "return from an Activity to a Fragment", simply because Fragments need to be put somewhere. Which means that hey need an Activity as a container. Putting aside some dirty overlay tricks.
So in the usual cases, you need an Activity to hold your Fragments. And since you have an Activity, you can have an intent-filter to handle your intent.
Activity hosts fragment, I think you should return to an Activity and select the correct Fragment. But there's always problem if you wanna select a Fragment freely, because you might have had a Fragment-Stack. If you don't have, ignore what I wrote below.
You have maybe three chance to reach your points. If you've called addBackStack, by default the Android use a backstack to control your Fragments, you have no chance to select your Fragments freely. so....
Chance 1 maybe worse case: Do not use addBackStack, and always use replace to finish your fragment's transaction.
Chance 2: Use FragmentTabHost. Then you can free select your fragments you've created, but be care of their life-cycles.
Chance 3: Use ViewPager, u know it ! :)
Its possible to retain a Fragment between Activities?
Lets say I have Activity A with Fragment F_Left placed at the left and Fragment F_Right placed at the right. If I want to launch a new Activity and keep Fragment F_Left... how can I do it?
Can I retain Fragment F_Left state between activities?
Note that I want to launch a new Activity because Fragment F_Left is my app menu and Fragment F_Right changes completely the context of the user operations... and my app have many of operations, so it makes sense to have an Activity per operation.
I know its possible to retain Fragment within an Activity, but as Fragment life cycle is closely tied to the container Activity I don't know if this is possible keep Fragment state between Activities.
Since API Level 13 (HONEYCOMB_MR2, June 2011), you can save and restore the state of a fragment across activities.
To save the state, use FragmentManager.saveFragmentInstanceState(), providing a reference to the Fragment whose state you wish to save. The Fragment must be attached at the time you attempt to save its state.
To restore the state, use Fragment.setInitialSavedState() with the return value when you instenciate the same Fragment.
myFragment = new MyFragment();
myFragment.setInitialSavedState(appState.getMyFragmentState());
fragmentManager.beginTransaction().add(R.id.container, myFragment).commit();
You can persist the SavedState object across activities as you would any other object; one way is to subclass Application as shown above (appState is the instance of our subclass).
Based on your response to my comment, I have a slightly different answer. It may not end up being the best answer in your specific situation, I'll let you decide that. :)
Right now you are bundling your fragments in activities because that is what made sense to you, but really, you can probably treat the entire process as one activity and use fragment transactions to hide & show (or create and destroy) fragments as needed.
Since you won't be creating and destroying activities, your menu fragment on the left will be left untouched, and you won't have any problems with its UI state. The set of operations you want to run (which no doubt includes all sorts of different fragments on the right) does not need to be launched in a new activity - but you will have to find a way to manage the logic you need for the fragment transactions (either in your one über-activity or in some kind of OperationsManager class).
I think this will end up being a lot smoother for the users of your application since the single activity just remains running - and you are only changing the parts that actually need to change.
If I want to launch a new Activity and keep Fragment F_Left... how can I do it?
Don't launch a new activity.
Can I retain Fragment F_Left state between activities?
Not automatically. It is not the same fragment. You would pass data between the activities for use by the fragment no differently than you would without any fragments at all.
To potentially answer your original question, if you fire off another activity then I believe that you can save your fragment from your first activity by calling FragmentManager::putFragment(...) when onSaveInstanceState(...) is called and then getting it back later, e.g. in onCreate(...).
However, I have to agree with Mark D's response.
Incidentally I'm doing something similar in that I have a dual pane setup whereby the left pane if fixed with a number of options with each option invoking a different fragment in the right pane. Furthermore selecting an entry in the right pane can result in the right fragment being replaced by another one.
However, I have taken the approach whereby by left fragment is only responsible for displaying and handling responses from the immediate fragment which appears in the right hand pane. Furthermore each right-hand fragment is then responsible for 'replacing' itself with a new fragment and handling results sent back to it. I'm using setTargetFragment, getTargetFragment, and calling onto the target fragment's onActivityResult method to pass results back.
For me the approach I've taken is no different from when my app runs on a phone with a single pane whereby the initial option's activity only knows about the activies it fires off and subsequently these new ones fire off further activies which they know about.
It should be mentioned that my activity in my dual pane app doesn't really do much apart from loading the left pane fragment and I can't quite see the need for a single activity to ever have to manage hundreds of fragments.