If i set a views visibility which as been inflated, to gone, will it Speed up my UI?
It will speed up the actual drawing of the UI, because, well, you don't have to draw it anymore, but it will still be inflated and the inflation process will not be faster.
GONE = This view is invisible, and it doesn't take any space for layout purposes.
Related
I have a ListView where each row of the listview contains about 10 ImageButtons. Most of these buttons have visibility = Gone and only show up in very rare scenarios. I am wondering if it's worth it to replace these ImageButtons with ViewStubs to avoid loading them (and the images they contain) all the time for all the rows of the listview. Then again their visibility is set to "Gone", so I am not sure what impact loading them has. Do their images actually get loaded or not?
Note that I am talking about replacing e.g. the 8 ImageButtons with 8 ViewStubs, not with 1
Cheers
A ViewStub is a dumb and lightweight view. It has no dimension, it does not draw anything and does not participate in the layout in any way. This means a ViewStub is very cheap to inflate and very cheap to keep in a view hierarchy. A ViewStub can be best described as a lazy include. The layout referenced by a ViewStub is inflated and added to the user interface only when you decide so.
Sometimes your layout might require complex views that are rarely used. Whether they are item details, progress indicators, or undo messages, you can reduce memory usage and speed up rendering by loading the views only when they are needed.
Simply a ViewStub is used to increase efficiency of rendering layout. By using ViewStub, manually views can be created but not added to view hierarchy. At the runtime, can be easily inflated, while ViewStub is inflated, the content of the viewstub will be replaced the defined layout in the viewstub.
The ViewStub will be loaded only when you actually use it/need it, i.e., when you set its visibility to VISIBLE (actually visible) or INVISIBLE (still not visible, but its size isn't 0 any more). ViewStub a nice optimization because you could have a complex layout with tons of small views or headers anywhere, and still have your Activity load up really fast. Once you use one of those views, it'll be loaded.
You must add ViewStub in Layout at first, after you can inflate it to another View.
Note: One drawback of ViewStub is that it doesn’t currently support the <merge/> tag in the layouts to be inflated. Alos ViewStub can’t be used more than once. Also keeping long-lived reference to a ViewStub is unnecessary, if it is required, it's good practice to null it after inflating, so GC can eat it.
Let's suppose your ViewStub ID is view_stub. You need to do the following in the activity:
ViewStub viewStub = (ViewStub) findViewById(R.id.view_stub);
View inflatedView = viewStub.inflate();
ImageButton button = (ImageButton) inflatedView.findViewById(R.id.button);
Now you can do whatever you want with the button :) That is, the inflate method returns the stub layout which contains the actual elements from the XML file.
Of course, you can always have the onClick XML attribute or can be dynamically called.
Is a ViewStub worth it?
->For the scenarios that you are specifying, I think `ViewStub` will be worth-shot.
See below urls about ViewStub
http://android-developers.blogspot.in/2009/03/android-layout-tricks-3-optimize-with.html
http://developer.android.com/reference/android/view/ViewStub.html
http://developer.android.com/training/improving-layouts/loading-ondemand.html
Instead of ViewStub you can try <\include> tag. The <include/> will just include the xml contents in your base xml file as if the whole thing was just a single big file. It's a nice way to share layout parts between different layouts.
Difference between <include> and <ViewStub> in android
Edit: just noticed that Endzeit commented regarding a similar direction before me.
I would start by doing some benchmarking around the inflating code with and without the views - just comment out the adapter code so it doesn't try to access the non existing views.
If the removal of the Views from the layout does gives you an improvement that you think is necessary and since you say the views are present only in rare scenarios which you are anyway checking for in your adapter,
then instead of inflating those views or even using view stubs, create them in code and add/remove them as needed (using the viewholder to reference them).
You could even go further and do a lazy creation of these views, similar to lazy loading of images, but I would only do that after running some benchmarking again.
I would use ViewStubs for loading complex layouts not simple ImageButtons.
Edit 2:
Looking into ViewStub inflate command, which is what it does when it needs to be visible you can see it infaltes the layout given and then adds it to the parent layout - since you are adding a simple ImageButton you can gain performance by not having a ViewStub and just adding the ImageButton in your code.
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/ViewStub.java#ViewStub.inflate%28%29
According to Google's official documentation here.
ViewStub is a lightweight view with no dimension that doesn’t draw anything or participate in the layout. As such, it's cheap to inflate and cheap to leave in a view hierarchy. Each ViewStub simply needs to include the android:layout attribute to specify the layout to inflate.
To experiment this, I created a sample project and added a ViewStub to the layout hierarchy. On running layout inspector I can see that all the layout attributes for ViewStub are zero.
Let's compare it to having a layout which has 10 buttons hidden. What this actually means is, the layout hierarchy has 10 buttons hidden, which is sitting in the layout hierarchy and taking up some amount of memory. It's cheap to leave a ViewStub in hierarchy since it doesn't take up much memory, at the same time it's cheap to inflate.
My final verdict would be, use ViewStub extensively when you've complicated views which are inflated rarely as it definitely helps in saving memory and improving View inflating time.
Using the Android monitor's Memory tab in Android Studio (button for the Android monitor should be at the bottom bar), you could check it yourself:
Take a look at the memory usage when running the app with invisible buttons
Take a look at the memory usage when running the app with visible buttons
If there is any difference, then you can conclude not everything is preloaded when the views are Gone. Of course, you could also compare this to a ViewStub implementation to check whether that will help to decrease memory usage.
In short, using custom view instead of viewstub.
We are having a similar situation now, and we have also tried viewstub before, listview works a little faster. But when it comes to 8 viewstubs, i don't think its a good idea to use viewstub to avoid inflate too many widgets.
Since u (and also us) have a logic to control whether 10 buttons to show or not , why not just define a custom view, and draw different buttons according to different state machine? It's much fast, and need no inflation at all, and it's logic is much better controlled. We are using this method to accelerate listview now and it works good.
when you set a view visibility to gone this means that This view is invisible, and it doesn't take any space for layout but its data are loaded into it.
Now the ListViews they remove the unseen or lets say the views that are out of the screen bounds for performance reasons .
A ViewStub is an invisible, zero-sized View that can be used to lazily inflate layout resources at runtime.
So i think if you want from my opinion I prefer the Views with GONE Visibility rather than using much logic with ViewStub and Creating and inflating ... etc .
But on the other hand
The rendering performance comes into picture when you are inflating
the views.
My guess is that its much cheaper to inflate a ViewStub than to
inflate a View, either from XML or by changing visibility. ViewStub is
especially used when you need to add/remove (indefinite) views (eg.
add phone numbers to a given contact). Hope this is what you were
looking for.
reference : ViewStub vs. View.GONE
some good Brief presentation of DDMS here :
http://magicmicky.github.io/android_development/benchmark-using-traceview/
Use ViewStub instead ImageButton.
This is because
. ViewStub is zero sized view by default while image button not
. View Stub is naturally an invisible view . its performance is better than image button because it load runtime only when its state become visible.
I've been using some progressbars in my android app (Lazy loading GridViews). So when each item is loaded I set the progressbar to become INVISIBLE. I know that
INVISIBLE : This view is invisible, but it still takes up space for layout purposes.
GONE: This view is invisible, and it doesn't take any space for layout purposes.
My doubt is when I set the progressbar to INVISIBLE does it mean that the resources needed by that View are still being used in the background? (Example the progressbar animation). If I set it to GONE will there be any change in performance (I know it might be negligible). I'm curious to know it's implications on performance. Thanks.
The performance difference would likely vary on what the view's contents and complexity are, and if there are nested views within it. While the layout information still has to be inflated into memory for the entire layout, the view measurements would not have to be calculated for a view that is GONE or its children, and it would not be drawn, whereas INVISIBLE only removes the rendering of the view (and its children) while still calculating the view measurements and its children.
If you don't want the view to appear again in the current lifetime of the activity or fragment, you can use parent.removeView(progressView) to remove it entirely for the best performance and memory optimization.
In your case it may not help much, but if you're going for bleeding edge optimization then I would take the approach to remove the view once it's done.
I'm making an app in which it might save me some time to
have a single layout for several activities, with some of the views set to GONE depending on which activity is being used.
I know that having a large number of views in a layout can lead to poor performance. If I had an activity with a large number of views, but a large portion of those views were to to GONE, would this activity still perform poorly. That is, do views that are set to GONE contribute to worsening performance? If yes, do they demand less processing power than VISIBLE or INVISIBLE views?
Thanks!
First thing you should know about gone vs invisible:
View.GONE This view is invisible, and it doesn't take any space for layout purposes.
View.INVISIBLE This view is invisible, but it still takes up space for layout purposes.
Thinking about the impact on measuring.
Which one is more efficient all depends on how frequently you are
changing the view's visibility.
For example, if the view is not visible for a majority of the time,
making it GONE would probably be more efficient, because the system
would not be needlessly measuring and laying out your invisible view
whenever it needs to adjust other views on the screen.
On the other hand, if the view changes between visible and invisible
frequently, you might get better performance from INVISIBLE as you
would potentially avoid an extra measure/layout on each transition.
Here is an interesting answer. I was wondering the same thing as you, and the answer is that View.GONE consumes more memory than simply calling removeView(view) on the view. However, GONE views do consume less memory than View.VISIBLE since they do not need to be drawn.
The memory amounts compare like this:
View.VISIBLE > View.GONE > removing the view from the container
What I do is use View.GONE on views that don't consume a lot of memory (like a TextView) and use parent.removeView(view) on views that are a lot of memory (like a WebView);
In Android, Which is the light weight view ?
ex:- View, Textview, Edittext, etc....
In some case we need to use a view to fill the area without showing the view to the user.
At the same time the screen should load fast.
You can use Space.
android.widget.Space
Space is a lightweight View subclass that may be used to create gaps between components in general purpose layouts.
If by "lightweight" you meant memory footprint, then there is none exists on Android, because each view have to derive from View, which itself is a massive object (well, not massive, it is about 8kB), so it's not that big.
But in terms of measure, layout and draw time the basic View performs well. You just have to set its visibility to INVISIBLE. And so it will be measured and put into the layout (contrary to GONE with which the view would not take up any space).
Unfortunately ViewStub is not meant to be used for this purpose. Its default visibility is GONE.
If you are really picky, then you can extend View and override methods like draw() (to do nothing, do not even call super), dispatchDraw(), setVillNotDraw(true), etc. (Take ViewStub as a sample).
You should have a look at ViewStub.
Use ViewStub if it is sufficient or LinearLayout which may be somewhat light weight.
I would like to make a LinearLayout that was created from xml invisible, and another LinearLayout visible to replace it. The replacement layout starts out as invisible. When I make the originally visible layout invisible, it still leaves space for it on the screen. How can I refresh the screen so that space is gone?
Perhaps you are mixing up View.INVISIBLE with View.GONE:
int GONE This view is invisible, and it doesn't take any space for layout purposes.
int INVISIBLE This view is invisible, but it still takes up space for layout purposes.
I have done this before and its actually very simple. Make 2 different layout xml files, one for each layout you want to show. When you want to switch from one to the other, all you have to do is call setContentView(R.layout.some_layout) and you're done!
pretty easy eh?