From Activity lifecycle we know, that in onResume the UI is visible. But if I set a breakpoint on onResume, I still don't see it, only after that. I heard there's some method which can check it, but I can't remind how it calls. We used it to make better animation. So how can I be fully sured that UI is ready?
Add global layout listener on view you want to check. Also please make sure that you remove listener once your work is done else it will keep getting called multiple times.
#onik shared a good link that should solve your problem
This ensures lay-outing. Drawing happens continuously and frame are refreshed according to sys clock.
I recommend watching: https://www.youtube.com/watch?v=Q8m9sHdyXnE
This will give you good idea on android drawing and layouting
Related
Good day,
I'm working on an application that will serve as a monitor of some sort for drivers. My client would like the application to work regardless of the orientation of the device.
I implemented the solution provided in the following article , and after fiddling a bit with the debugger, I can see that the Asynctask is still working. However, the TextViews and ImageViews it is supposed to work on are not working anymore.
Here is the code of my TaskFragment.
To clarify : The AsyncTask still receive and handle the elements correctly, but the elements of the layout are not updated anymore. I would like to know how I can keep them working.
I would suggest using an AsyncTaskLoader as those can re-attach to whatever lifecycle element you created it in relatively easily. See here: https://developer.android.com/reference/android/content/AsyncTaskLoader.html
It might seem pretty involved to implement at first, however if you read https://developer.android.com/guide/components/loaders.html, most of the weirdness should be cleared up.
TLDR: Using AsyncTaskLoader allows an easy way for your AsyncTask to be reattached to your fragment after it is destroyed and recreated. You just need to call getLoaderManager().initLoader(...) in the onCreate of your fragment.
Ok, so I found a (probably not very efficient) workaround, but a workaround nonetheless.
The problem was that, after an orientation change, since the Activity is destroyed and recreated, the variables batterymonitor, valuemonitor, etc, would not point towards the new objects created because of the layout/activity change.
As a solution, I am now using a findViewById each time I need to do an operation on the layout. This way, the id is permanently refreshed to keep up with the activity changes on a rotation of the device.
The ugly line I use to do so is :
batteryMonitor = (ImageView)getActivity().findViewById(R.id.batteryMonitor);
batteryMonitor.setImageResource(R.drawable.no_battery);
I wish to sometimes (when a flag is on) update a few UI components in an Android activity every drawn frame (i.e., not while app is not visible, and not more than once per frame). How do I do this?
The question specifically states "every drawn frame", which suggests that overriding onDraw() in whatever it is that's being drawn will solve your problem exactly.
If that's not quite what you're going for, you should take a look at Choreographer, which invokes a callback once per display refresh. You must renew the callback every time it is invoked. To stop the callbacks when the Activity is in the background, establish the callback in onResume(), and set a flag in onPause(); if the callback sees the flag set, it doesn't renew itself.
The documentation for Choreographer notes higher-level API features that do common things. If one of those fits your needs, prefer that over the use of the lower-level API.
I'm curious guys,
What are the exact cases doTraversal -> performTraversals is called? Since I have pretty heavy Activity, I want the application to call onDraw or the sort. performTraversals is pretty heavy, it is trying/measuring if it should resize views, stuff like that I guess. And I don't need it when I'm making some view, that no other view is dependent on, GONE, but I guess I can't skip that. So before digging into the source of Android, I want to ask. If you know it, please feel free to share :)
Thanks,
Danail
performTraversals() has many jobs but its three main roles are:
Measure views
Layout views
Draw views
Every time Android needs to redraw a window, performTraversals() is invoked. It does not mean however that measure/layout happens every time performTraversals() executes. You cannot skip performTraversals() if you are using a standard views (only SurfaceView lets you bypass this when drawing.)
I'm reading up on SurfaceView and how to use it, and I've come across some information that states that a SurfaceView has View#willNotDraw() set to false by default, and that it's up to you to call SurfaceView#onDraw(). I also read that RomainGuy said that this is done by default because it is more efficient. My question now is, when should you handle calling SurfaceView#onDraw() in a separate thread, and when should you just set View#willNotDraw() to true, and just call SurfaceView#invalidate(). Is there a difference between the two, and does one improve performance more than the other?
See:
http://developer.android.com/reference/android/view/View.html#setWillNotDraw(boolean)
I'm not sure where you got your information, but at least the javadoc says that most users will set this to false to get Android to send it onDraw events itself. As for your question about when you should do this, I would say it comes down to why you're using a SurfaceView.
If your view is displaying something dynamic (e.g. for a game or something that has a tight event loop), you'll want to be controlling exactly when updates happen, especially if you'll have the information to use one of the more detailed forms of invalidate to save redrawing the entire View. You won't want Android to call invalidate for you, and that's why the flag is there.
If, on the other hand, you are simply drawing something static, it makes sense to let Android's UI stack control the invalidations.
By the way, invalidate only posts a request to re-draw the View, so be aware of this if you intend to use the event-loop style (onDraw will be called sometime after you call it).
Edit: some clarifications.
Using SurfaceView.onDraw() and SurfaceView.invalidate() will make SurfaceView behave like a normal View and you will pay for the extra overhead associated with SurfaceView. If you want to draw from the UI thread, use a regular View instead. It's easier and cheaper.
I am changing the value of several RatingBars upon completion of a child activity (inside the onActivityResult() callback). My problem is that the parent activity has not finished drawing before my RatingBars value-changing code is executed, so I get some funky lag and a half-way completed "animation" before the parent layout has even been displayed.
I'm familiar with the document.ready() function in jQuery, which waits until the DOM is completely ready to commence any script therein.
Is there any way to achieve the same result with Android? In other words, I need a way to wait until an activity has completely finished drawing itself to the user's screen before some code is executed.
This might be a simple thing in Android, but I'm pretty noob. Thanks for your time and help.
-Steve
Could you simply put the code in the onResume method which will be called after the views have been set up?? (Not sure if this include getting drawn)
Another possibility is to create a handler and dispatch a method to it at the end of the onCreate method, this will get run on the UI thread but I imagine this won't get processed until the UI thread has finished the more important stuff (i.e. drawing the views)
This is largely just me putting down possible ideas, I know there is a way of achieving this I just can't remember how.