Working with onPause, onRestart, in Tab Widget - Android - android

I have a ListView that is inside a TabWidget. When I select an item on the ListView and go to the child ListView, the TabWidget disappears. This is fine, except that it invokes the onPause method, and thus causes onRestart to be called when I return to the parent ListView.
I have onRestart setup to retrieve updated data from the server, but I do not want this to occur everytime the user returns to the parent ListView. I only want onRestart to be called when the app comes alive from running in the background. I have tried implementing a Boolean variable to determine if I should execute the code that is inside onRestart, but there doesn't seem to be a way to get around the effects of this.
Ideas?

You could fire off your child activity with startActivityForResult and set a flag in onActivityResult to not reload (which should be called when the user backs into the listview from the detail page). You'd have a member variable (let's say mReload) that you'd set to true in onCreate and onRestart, and to false in onActivityResult, then process the reload onResume if mReload is true (and set it back to false so a normal resume won't trigger the reload).
Alternative: just set a flag (mLeftPage) in your activity on the row's click listener. On restart, if mLeftPage is true, don't reload the list and set mLeftPage back to false. Otherwise, reload.

Related

How to call a method on an Android Fragment to start an activity?

I have an Android application that's using a SectionsPagerAdapter to create 3 separate fragments. What I would like one of the fragments to do is to automatically call a method (which launches an activity) whenever the user navigates to it from a tab bar. For example, right now I'm using the on resume() method to launch the activity. I also have a button set up to do it.
However, when I trace it through the debugger, the onResume() is only called when the fragment is first created. I've tried setting the fragment to null and recreating it from the SectionsPagerAdapter, but still none of the lifecycle methods are called. I've also set up a separate method in the fragment to launch the activity and calling it from the SectionsPagerAdapter before returning the adapter, but that doesn't launch it either - it just shows the display.
As I mentioned, the display has a button which allows the user to launch the activity manually, but that means the user has to press a button twice - once to get to the page, and once to launch the activity.
Is there a solution to this problem?
Call startActivity() at onTabSelected() method.

Android fragment event listeners

As i understand it, would it not be better to create a fragments event listeners in the fragments onCreate? If it is done in onCreateView it would have to be redone everytime the fragment comes back into view (onResume())? Would it make a difference where it is set?
1) yes it can be better
2) yes you are correct, as event listener is initialised there than the process will be repeated here
3) please have a close look at life-cycle method
4)it always makes difference where you are using and when you are initializing.
An event is set on a view and hence is restored when the view is restored. For example, lets say we set a listener on a button in a fragment that is created in onCreateView. If at some point of time, if the fragment is restored (without a call to onCreateView), the button is restored along with the listener that is set. The same goes for setting a text/background for a button - you don't have to reset the text/background each time the fragment is resumed.

close a slider after an intent is launched

I have an activity, DogActivity, with a slider. When the user slides view PawsView to a certain degree, I start another activity, CatActivity, using startActivity(intent). If the user clicks the back button, normally the user returns to DogActivity. Here is my problem: if in Developer options I set Do not keep activities then when the user clicks the back button and thus returns to DogActivity, the slider is not asserted and so PawsView is back to its original position; however, if I don't have that option selected, upon returning to DogActivity the slider is still asserted (the sliding already occurred).
Since I don't want to depend on the user selecting or deselecting Do not keep activities, I need to do this programmatically. So does anyone know how to do this? I have tried putting the appropriate code inside onResume but that has no effect. It's as if finishing CatActivity has no effect on DogActivity. BTW, the view I am using to display PawsView is a custom view.
I already tried using a handler with postDelayed to pull PawsView back to normal, but the handler always executes before the startActivity is executed. If on the other hand I start a proper Thread to run the call to close the slider, I get an error about the wrong thread trying to change the layout.
Another way of asking the question may be: How do I force onResume to be called even when Do not keep activities is NOT selected on a user's device.
You could try to launch CatActivity using startActivityForResult and then handle the result in onActivityResult and do the necessary setup from there. It's sort of like forcing onResume.

How to handle activity coming to foreground again

The books I have are abysmal at explaining how to work with the lifecycle, there's a lot I'm missing that I'm hoping somebody can fill in.
My app structure is that when it's first started, it starts an activity full of legalbabble that the user has to accept. When he says 'ok', I start my main activity and then I call finish like this:
public void onClick(View view) { //as a result of "I accept"
Intent mainIntent = new Intent(mParent, EtMain.class);
startActivity(mainIntent); // Start the main program
finish();
}
Then in EtMain in the onCreate method, I've got some tabs and I instantiate some classes:
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
SetupTabs.setMyTabs(mTabHost, this);
mComData = new ComFields(this); // Create the objects
mDepWx = new WxFields(this, DepArr.Departure);
mArrWx = new WxFields(this, DepArr.Arrival);
mDepVs = new DepFields(this);
mArrVs = new ArrFields(this);
mTabHost.setOnTabChangedListener(new OnTabChangeListener(){
}
Questions:
The 'finish' in the first fragment should terminate the legalbabble activity so it'll never be restarted, right? And the EtMain one will remain forever (until killed externally), even if my app gets pushed to the background, right?
The way it is now, when EtMain gets pushed and later brought to the foreground (by tapping on the icon), it goes through the legalbabble screen as though it's a complete start - that's what I'd like to prevent - going thru the legalbabble screen again.
It would seem that I'd want to override onRestart in the second code fragment and put something in there to restart the app, right? That's the part I'm unclear about.
My question then is what needs to be done in onRestart. Do I have to recreate all the tabs and data in the tabs and all my object instantiations? Or is the memory state of the app saved someplace and then is restored back to the state that it was in before something else was brought to the foreground in which case not much needs to be done because all the objects and listeners will still be there?
Yes after the first activity has ended you shouldn't have to view that activity again. You could also write to the shared preferences that the user has previously seen legal info.
If you're UI object creation is in the onCreate method, this should only be called once. Pausing or resuming will not call the onCreate method again.
Unless you explicitly remove your objects and tabChangedListeners in the onPause method, you should not have to touch them in the onRestart method.
Correct, the state of the app is saved automatically. You shouldn't have to touch the onRestart method.
Hope this helps!
I think the problem is that the launch activity in your manifest is the legalbabble activity, so when you click on the icon, the system launches another one. A better architecture would be to launch the legalbabble activity it from your EtMain activity in the onCreate method of the latter, using startActivityForResult. From the docs:
As a special case, if you call startActivityForResult() with a requestCode >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your activity, then your window will not be displayed until a result is returned back from the started activity.
When you get the result in onActivityResult, you can call finish() if the legal stuff was declined; otherwise everything will proceed normally.
This avoids the problem that the launch activity defined in your manifest finishes when the legal stuff is accepted.
EtMain will not remain forever, if the user backs out (by pressing the BACK key) the Activity will be finished (onPause, then onStop, then onDestroy will be called).
In general you can ignore onRestore until you are doing something complicated.
Once the user has exited your application and re-enters (or presses the icon on the Homescreen), onCreate (followed by onStart and onResume) will be called for your first activity, so you do not need any logic in onRestart, your code in onCreate will do the setting up for you as it did the first time. Because of this your legal babble will appear again when the user starts the app after exiting unless you store a preference (in SharedPreferences or a database or file) to indicate you have already displayed it - in which case finish it straight away and start the main activity.
onRestart is only called when the application goes from the stopped state (onStop has been called but not onDestroy) to the started state (onStart is called but onResume has not yet).
For saving data - some components save their state automatically (e.g. EditTexts remember the text in them, TabHosts remember the currently selected tab etc). Some components will not. If you wish to save extra data then make use of onSaveInstanceState and onRestoreInstanceState. You should only use these methods to restore the state of your application or temporary data, not important things, e.g. the id of the resource what the user was looking at, what zoom level they were at etc. For things like contacts or actual data you should commit these changes to a database, SharedPreferences or other permanent storage (e.g. file) when onPause is called.
I recommend taking a look at the Android Activity lifecycle if you are confused. Or ask more questions!

Activity is not restarting on tab changed in android

I am making a activity using Tab-Host.
I have two tabs. When I start the tab-Host activity, the tab-Host opens the activity and the life-cycle of the activity is calling but when I changed the tab and again open that previous tab the activity is not getting its callback methods like resume.
I don't think there is any specific reason it should restart. For changing configuration (like rotating the device or sliding out a keyboard) there is a specific trigger because the app needs to deal with the change. But any other process should go according to the Activitvy lifeCycle
When your app goes to the background (looses focus) for any reason you get onPause() called, and when it goes back, your onResume() will be called. This is the same for when you go home and then back to your app, or when you switch activities like that. No new intent or something like that, just going back to the activity.
You should put your code that needs to run in the onResume().
Do what you need to do in the activity in onResume() instead. That will get called everytime, not just the first time it is created.
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
When you switch from one tab to the other and back, the first tab only gets its onResume method called since it has already had its onCreate called the first time.
You can run the code you like in your onResume method if you want anything specific to happen when it gets focus again.

Categories

Resources