Android - More than 80 views - How to increase performance - android

My activity currently has more than 80 views and now I´m getting the error, that this is (obviously) bad for performance. So, what can I do to increase the performance?
Is it possible to only load the views that are visible on the screen?
These are the views i´ve to repeat over and over again:
http://i.imgur.com/Opc1KEA.png

There's no way you're fitting 80 of those on your screen, so as you mentioned, you only want to load the views that are visible on the screen. You need to implement an Adapter. Depending on your layout that might possibly be in conjunction with a GridView, but almost certainly some sort of layout that subclasses AdapterView.

Related

Best practice for displaying tall, rich content in Android. ScrollView or ListView?

When displaying a screen with various sections ordered vertically, where each section looks different than the other (so maybe recycling items wouldn't use an actual recycle but a recreation), would be any true benefit to use a recycling view group, taking into consideration that no large bitmaps will be displayed, instead of an plain ScrollView?
I suspect there is a performance impact when using ListView for example, that might affect scrolling, and an slight increased memory usage, maybe a delay (only when layout is measured - not that often) when using ScrollView, but are these that significant for 7 sections, for example, where 3 of them are visible at a time?
Thank you!
This is mostly speculation, but I would consider it relatively well-informed speculation.
Let's assume you have 1000 sections, each of them different from the other. My understanding is that both ScrollView and ListView will have "problems" here, though the sort of problems they'll each have will be different.
ScrollView will measure and lay out all of its children up front (which will probably be quite expensive and will probably cause quite a delay in your UI). And it will have all of those views inflated and hanging around in memory (which might cause your process to crash with an OutOfMemoryError). But if the delay were acceptable and if you had enough memory for everything, at this point your app should run perfectly smoothly (i.e. no frames dropped when scrolling/flinging).
ListView, on the other hand, will only measure and lay out those children that are currently on-screen, as well as a few extras that are immediately off-screen. So initial performance should be quite fast and memory consumption should be quite low. But you mention that each section is "different", so view recycling won't "work". In practice, this would mean ignoring the convertView parameter of getView() and inflating a new view each time. If your sections are complicated, this could easily cause frame skips during scrolling/flinging.
But you mention that your app will have only 7 sections, or about 2.5 screen's worth of UI. For such a small number, I think worrying about performance before simply trying something out is silly; I suspect that a ScrollView holding a LinearLayout holding all seven sections would work perfectly well on all modern devices.

Are too many views in XML bad?

I have an XML file with about 150 views. Yes, I know it is a lot and I did get a message from Android Studio saying I can't exceed 80 views. But I can't drop views any lower than 150. I considered using list view but it works the way I wanted it to.
The question is, will this many views make the app crash/slow the device? I've tried it on my s7 and it works perfectly fine. My lowest API is 17 which is 4.2. Wouldn't 4.2 devices be able to handle this XML without any problem?
Thanks.
The problem with having an excessively large number of Views is that Android often needs to measure, layout, and draw them, and it will traverse the entire View hierarchy to do this. If the number of Views is so large that this traversal takes more time than the screen refresh rate, you will skip frames and your UI might appear to lag or be choppy.
If not all of those Views need to be on screen at once (for example, if you are using a ScrollView to hold a very large container that the user can scroll through), then you should probably switch to using RecyclerView.
If all of those views need to be on screen at once, then you might consider writing custom Views that can display your content all at once instead of having individual Views that draw individual things. This can drastically reduce the time and complexity of the measure/layout/draw traversals.
It's difficult to suggest an approach without knowing more specifics about your UI, but hopefully that explains the issue.

ListView performance with complex views as list items

I had ran into problem with performance. I have to develop complex ui based on ListView and really complex item layout contained nested layouts, custom views, lot of images etc.
The problem is as usual, when client is creative and has no limit credit card: performance.
Creating of list view lasts ~10 seconds on fast device.
When I profiled application, I discovered, that most of the CPU power is used for onMeasure method - you know how it works - measuring of the width, passing measure demand to children, getting them into lauouts, asking layouts to change it's height, then measure once again with new bounds - horror.
I can't show you the screen with the layout - just say that there is ~80 views in each item - no we can't do less.
My idea is based on simple observation - every single one sub view on particular device has this same size - i.e. if I have an image view to display inside the list item - on each item it will have exactly this same size.
So I want to make some cache for dimensions - i.e. - I have LinearLayout containing bunch of views, I want to perform simple algorithm:
Create CustomLayuout extending LineraLayout
put members like width, height (i.e. static)
when view is created for a first time I want to get it's size put it into static vars and reuse them when next instance of the view will be created.
After this (a bit long) description finally my questions:
Can I apply approach like that, or there are some serious
disadvantages?
How to do it (code sniplets welcomed)?
Thank you in advance

Full-screen tabular layout

I have 12 basically identical views which I want to arrange in a grid that covers the whole screen. Depending on the device's orientation, I want to use a 3x4 or a 4x3 grid.
As far as I understand, there are basically three approaches to this topic:
Use a GridView
Use nested LinearLayout instances
Use a TableLayout
I'd like to have a layout that
automatically adapts to orientation changes (as GridView does)
uses all available screen space (as nested LinearLayout instances do)
doesn't allow scrolling (and without that "can't scroll any further" effect of the GridView)
allows me to force the same size on all of my items
By default, GridView has scrolling and doesn't fill the screen, whereas LinearLayout and TableLayout don't automatically adapt to orientation changes.
Currently I'm using a GridView with disabled scrolling and a custom adapter which sets the item views' minimum height depending on the orientation and the container's height to force a filled screen. This works but feels like a really ugly hack.
Dynamically constructing nested LinearLayout instances depending on the orientation would probably also work, although I haven't tried that.
This seems to be a frequent goal (1, 2, 3, 4), but all the suggested solutions are either as hackish as mine or don't satisfy some of my requirements.
As I'm new to Android development I'm not sure whether I'm missing something.
What is the optimal way of implementing this?
I'm targeting API level 8 and above.
Use a GridView
A GridView is a widget that you would use when you want to show data in a grid like manner with a larger set of data(as the GridView's recycling mechanism would provide a greater performance than a normal built hierarchy). This is not your case as you want all the views visible from the start and from my point of view the overhead of a GridView isn't simply worth it.
Use nested LinearLayout instances
A good option but avoid nested weights. You could use instead two LinearLayout with weights on the longest direction(vertical for portrait and horizontal for landscape) placed in a RelativeLayout with a centered anchor view.
Use a TableLayout
Another option. Use the stretchColumns option for the width and weight on the TableRows for the height.
Depending on the device's orientation, I want to use a 3x4 or a 4x3
grid. What is the optimal way of implementing this?
There isn't an optimal way, either of the solutions above could be used, you could also make your own layout.

Complex RelativeLayout-based View - performance issue

Got a performance issue when lots of nested RelativeLayouts are used.
For example if we have some RelativeLayout as a UI root, and every container(button, label, textview, imageview) is a RelativeLayout + Android based component (ex. aButton = RelativeLayout + ImageView + TextView), then in a complex view of 4 buttons, 3 images and 6 labels we get ~15 nested RelativeLayouts.
RelativeLayout has a very complex onMeasure method, that calculates size of every child to determine the size of layout. Calculating size of a complex view of 15-20 nested RelativeLayouts costs ~5 seconds, that's too much. onMeasure is most expensive of all calls, even drawing finished much faster then measurement.
<=UPD=>
To prevent appearing suggestions to use native android views to build something complex: Ability to add everything to everything is required. That's why every container has to be not just View, but ViewGroup. And RelativeLayout features like gravity and alignment can also help alot, that's why lot's of RelativeLayouts are used.
<=/UPD=>
Had anyone got these performance problems?
Should replacing RelativeLayout with some other Layout solve issue?
Or removing all these nested layouts is the only way to deal with the problem?
Does anyone know how much layouts can be nested without some performance problems appearing?
It definitely depends on your testing device. But you should check the hierarchyviewer (within the tools directory) for unneccessary nests of views in order to remove them.
Also your aButton sounds like a stock ImageButton. So you could replace at least that with a standard solution.
If you posted some code it might be easier to tell whether there are more items that could be replaced by stock solutions.
After a few tests came to conclusion that having more that 12 nested layouts does a great impact on performance.
On average 10-11 nested layouts should work fine.
For example 12 nested layouts with 12 children on each display in 6 seconds on device, and in 9 on emulator.
It was my understanding that the whole point of relativelayout is that you don't have to nest them to the nth degree. Why not just use a few RelativeLayout s rather than 1 per component?

Categories

Resources