The answer I expected at first was the show method. Unfortunately if show has a lot of work to do, there is a delay between method call and screen appearance. So how does one get notified when screen appears?
Using show() should be fine, the screen will be shown straight after so just put stuff you want done at the end where the delay should be negligible.
If the work that show() does is in a super class, then just override it, call super.show() and then do your stuff after, like so...
#Override
public void show () {
super.show();
doAnyOtherSlowStuffThatMightNeedDoing();
doTimeCriticalStuff();
}
I should probably add that a better solution would be to not do slow stuff in the show() method to start with, but that's a whole other debate.
Related
How do run a function after the view and its subviews have finished loading like in iOS (viewDidAppear / viewDidLayoutSubviews)
I basically want to run a UI animation after the program loads but as my programs too heavy(and has many subviews) the animation doesn't run at all(I tried handler.postDelayed and it worked fine but I wanted to know the more efficient way to do this(for performance reason as a phone I tested on is quite old and takes 4s to load while another takes just a second, etc.).
I think you can use the ViewTreeObserver for that as stated here.
You will have something like:
yourView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// do something here but make sure you unregister if you just want to get notified only once..
}
});
The developers page is stating the following: Register a callback to be invoked when the global layout state or the visibility of views within the view tree changes
You can then add this listener on the root view of your activity for example in onCreate and inside that method you can execute your animation.
The method gets called whenever the layout state or the visibility of the view gets changed. It is not like viewDidAppear but it is something similar to "viewDidLayoutSubviews".
You can also try to run the animation in onResume but that will run the animation whenever the activity resumes not only the first time you create it and I am not sure if you want or not that.
I'm facing a huge problem with LibGDX screens.
As we know, Screen interface has some methods and one of these methods is show(). I thought that this method is called when the screen becomes 'visible' for the user - but it's not, it's called earlier (but after the constructor).
My question is:
Is this possible to detect the moment when the screen becomes fully visible?
If by "becomes fully visible" you mean when you should begin drawing something. Then I would guess its the first call to render(). render() is called after the constructor, show() and resize(). So the first call to render() would be the moment you make something visible on the screen.
But this does not stop you from drawing on the screen before you call render() or loading assets inside render().
So if you mean "when is the Screen done initializing/loading" then only you can decide that with your code.
As per my observation, the call sequence of screen interface is:
1.public void show() {}
2.public void resize(int width, int height) {}
3.public void render(float delta){}
pause() and resume() called when you minimise or maximise your application.
in resize() method which called just before render method where you can write your code to do something just before render().
I'm trying to create a program which will randomly and continuously display circles all over the screen that will change sizes. I've created a method that will draw circles but I'm not sure how to call it. In the past I've only done buttons which will call a method when clicked, but I don't know how to just call a method out of the blue. Is there a 'main method equivalent' in android which is automatically run?
The onCreate method of the activity showing the circles will be automatically run. From here you can start a background timer thread to randomly call the method creating the circles.
There is a main method, but you can not touch it simply. In Android , the UI thread would be the main method you want though they are not the same thing.
You can run action in UI thread like this:
public static void runInUiThread(Runnable action) {
if (Looper.myLooper() == Looper.getMainLooper()) {
action.run();
} else {
new Handler(Looper.getMainLooper()).post(action);
}
}
But according to your question ,you want to display something. It is not a google idea that draw it directly on Activity, you can create a class and extends View. The Override the onDraw method , you can put your drawing code into onDraw. This function will be called automatically when it need to be display.
Now you can put your custom view into layout and if the custom view need to be display in screen , it would.
You can create your own class enxtends View, and put the code that controlls the appearance of the circle in the mothod onDraw() which you should override.When you want to get the size of your circle changed, call invalidate().As a result, the method onDraw() is called and the appearance just changes.
I am not sure if this is possible or not but what I am after is that, I have a method which I called in my onCreate and the method runs when the app is starts, basically this method does bunch of things like put numbers on Textview, change colour of text etc (this method does around 12 things atm). I have a button, what I want to do is, when the button is pressed I want to stop using the method that was called on start. For example;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpMethod();
removeMethod();
}
public void removeMethod(){
Code for button and listener
.......
.......
.......
.......
{
you can do it with putting it in a thread, you can pause/stop as you wish.
here is simple tutorial on thread in java, you can put your in a thread which you want to do in setUpMethod().
http://www.tutorialspoint.com/java/java_multithreading.htm
and use Thread control methods to control the execution of code.
http://www.tutorialspoint.com/java/java_thread_control.htm
You just need to read through setUpMethod(), work out what the reverse of each action of it is, and put all those undo steps in removeMethod(). Post the code of setUpMethod() if you need more help.
If you do those things on main thread, you can't stop, because everything you do is on one threat. 12 things should finish and after this removeMethod() will be called.
Simply revert all those 12 changes to initial state in removeMethod method -set text, textColor and other things to initial values
To "stop the method being called again when the button is pressed", create a boolean somewhere, and add the line
if (wasRunAlready) return;
to the start and
wasRunAlready = true;
to the end of setUpMethod(). It will then be impossible for the code inside to run twice.
when I add a ViewFlipper, the UI thread seems to wait for the onCreate() method in the activity to be finished. Then it shows the second view. Why does it happen?
My current code is:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu);
viewFlipper = (ViewFlipper) findViewById(R.id.ScreenSwitch);
viewFlipper.setInAnimation(AnimationUtils.makeInAnimation(this, true));
viewFlipper.setOutAnimation(AnimationUtils.makeOutAnimation(this, true));
//do the necessary loading, when the splash screen persists
doSomeLoading();
viewFlipper.showNext();
}
Actually, the doSomeLoading consists of a for loop counting to ten millions and doing nothing. Now it just waits for loop to be done and shows the second view.
I would really appreciate a solution without having to create a separate Thread, because it seems to be pointless, invalidate() doesn't help there.
Maybe with viewFlipper.showPrevious();?
EDIT
I don't have your full code but here is the idea :
When you do long loading or slow actions, most of the time, you can think AsynTask or background thread.
So you need to create a new inner class. Lets say AsyncLoader. You will implement the method doInBackground() of this class and put your doSomeLoading() in it.
Now, implement onPostExecute() and put your viewFlipper.showNext(); in it.
Then, in your onCreate() method, replace the doSomeLoading() by new AsyncLoader.execute();
This should be nice. I might have forgotten some stuff as it's not real code. Check this for more explanations.