I want to use CardViews in my app only for the visual effect.
All CardViews will contain very different views, so I cannot really design a good adapter and thus I cannot use a RecyclerView.
The result is perfectly clean, but for this I had to nest a lot of ConstraintLayout, and so the layout take several seconds to draw itself. (any advice on how to measure more precisely this delay ?)
Here the hierarchy of my layout (with 9 CardViews and not 2):
ConstraintLayout
-Image + text x4
-ScrollView
--ConstraintLayout
---Cardview
----ConstraintLayout
-----text, spinner, button, etc
---Cardview
----ConstraintLayout
-----text, spinner, button, etc
You can see the max depth is ConstraintLayout>ScrollView>ConstraintLayout>CardView>ConstraintLayout, which seems inefficient as hell, as stated in the Android Optimizing Layout Hierarchies Guide.
What should I do to flatten my layout ?
I think your setup is fine. And not too deep. The layout is probably not the problem.
Note that it only draws the item on the screen. It does create layouts for the others in the ScrollView, but does not render them. If the drawing was the problem, the scrolling would be slow. You can check that.
Layout might be slow, but I doubt it. There are ways to monitor this though.
Are you loading all images off the UI thread? Nothing on the screen is coming from a server or going through some other complicated (parsing) method?
SOLUTION 1:
It's okay for RecyclerView to load different views and you can design good adapter for it. Check A RecyclerView with multiple item types and Heterogenous Layouts inside RecyclerView.
SOLUTION 2:
Considering your hierarchy you can place your cards directly to ScrollView without ConstraintLayout:
ConstraintLayout
-Image + text x4
-ScrollView
--Cardview
---ConstraintLayout
----text, spinner, button, etc
--Cardview
---ConstraintLayout
----text, spinner, button, etc
Here is an easy solution: Don't use nested ConstraintLayouts, the idea of ConstraintLayout is to reduce the amount of nested objects, but there is a performance price for it.
Base on this comment it's up to 3 times slawer than RelativeLayout. And I think that nesting it only increase the problem.
So try replacing ConstraintLayout with RelativeLayout and please reply here with the difference in performance, I bet you will see one.
Related
I am trying to achive this:
First I tried by putting all my recyclerviews (with WRAP_CONTENT) inside a nestedscrollview. That worked, but the performance was awful. Then I tried to set a height for my recyclerviews, that was a lot better (especially the first gridlayout and the horizontal linearlayout loaded very fast), but still had the problem with the dynamic "category" part.
Now I am trying to put all my recyclerviews inside a single recyclerview with different viewtypes. Since that is a pretty big deal (I need to refactor a lot of code because I have diveded every area from the screenshot inside a single fragment and now I need to put all that code inside an adapter) I wanted to ask if I can actually expect any gain from this, because in the end its again a "nestedscrollview" (made by myself, but...). Or if there is some other "best practice" way to achive this layout.
Thank you
Edit:
As expected this didnt do the trick neither. When just the two first recyclerviews are added as viewtype it scrolls and loads smoothly. But as as soon as I try to add the category items (below the category), I notice a lag and especially when selecting multiple categories and scrolling fast up, there is noticable lag. I guess I will have to change my layout and move the category selection part inside a separate view, just need to come up with a user friendly solution. But its acutally quite dissapointing that, in my opinion such trivial task, laying out multiple tables, is such a pain in the ass on android.
I didn't manage to get it working with standard android stuff.
Now I am using epoxy from airbnb ,and I have converted all my views from nestedscrollview to the epoxy recyclerview. Its a great library, and airbnb use it too for all their views.
Nevertheless it's sad that the android dev team doesn't address this problem and provide a solution besides the info "don't nest multiple scrollviews(recyclerviews) that scroll into the same direction".
You can use Recyclerview in recyclerview.
https://irpdevelop.wordpress.com/2016/02/10/horizontal-recyclerview-inside-a-vertical-recyclerview/
And make sure to use multiple view types.
I would like to create a grid layout in which each item is taking as much space as possible (minus padding), but only as long as there are columns available (after that the next item would be inserted in the next row while keeping the size). Additionally, each item must be a square and is added dynamically.
Example layout with 10 items would be as follows:
I have tried to achieve this by setting weights, ratio constraints, overriding onMeasure - but I just can't get it to work. I would be happy with either a programmatic or an XML-based solution (as long as each item can be added programmatically). I would prefer the solution to be in Kotlin, but I would be happy with a Java-based one as well.
It's probably worth saying that each item in the grid layout is a layout (RelativeLayout as of now) to make inflating it and setting a layered background drawable programmatically easy.
I think you might be able achieve what you want with a different Layout
Have a look at https://github.com/google/flexbox-layout it has lots of methods to control how the cells grown or shrink and includes automatic or manual wrapping of cells.
Take a look at RecyclerView. You would need to pass GridLayoutManager. This tutorial may or may not help you. For square items, I suggest using CardView but it's not necessary. If you are targeting tablets as well as smartphones, check this out. And for dynamically adding new items, you should notify recyclerView's adapter. See this link. You can also extend RecyclerView or GridLayoutManager for more control over items.
I searched for a few hours over the internet but I didn't find any example or documentation explaining how to create an horizontal list view with fixed number of elements.
Basically, I would like to have, let's say 3 elements out of n(total number of elements) which are displayed on the screen without taking into consideration the size of the scree. The elements can be bigger or smaller proportionate to the screen but the number of visible elements should be the same, fixed. see the image.
How can I do that? Any hint is appreciated! Thank you!
You can use TwoWayWiew third party library (i dont really recommend this solution), or if you want to avoid to use lib for this, just use RecyclerView, and you can set HORIZONTAL param to layout manager.
I would not use a ListView for this, but a RecyclerView instead. Performance is better in a RecyclerView and I honestly find them easier to work with. You can allow for horizonatal scrolling via the LayoutManager for your RecyclerView.
If don't mind scrolling horizontally by 3 items you could use a ViewPager with each View containing a LinearLayout (orientation horizontal) with three of your elements that have a
android:layout_width="0dp" and an
andriod:layout_weight="1"
for even distribution.
When you "scroll" you would just animate the next "page" into the screen bringing in the next 3 elements.
This might not be the most elegant solution but I think it would behave the way you want.
use the linear layout with its orientation set as horizontal under the relative layout
My app is quite complex, i have a lot of views and viewgroups.
I have already turned some of the nested linearlayouts into relativelayouts, but the tree is still quite deep.
In the views tree there are branches that i need to display only sometimes, i would like to know what performs better: a sub-tree to show and hide or a dialog?
Here's a rough image i've done to try to explain:
Image clearly shows: 4 views is better than 7, but what if i hide (gone) viewgroup #5?
How heavy is opening/managing a "complex" dialog?
What are the pros and cons?
Thanx.
Using nested layouts is not recommended because of performance issues.
Well some layouts can only be made by doing some level of nesting. But you should avoid having too many nested LinearLayouts and even more important NEVER nest LinearLayouts with weights. You can read a little more about optimizing layouts in the official docs.
Personally I use LinearLayouts for simple stuff and start using RelativeLayout when the layout gets more complex. So, my suggestion would be to use the dialog. It will also help in making the code easier to read.
I have a ListView with each item being a custom layout with multiple Views (including a large image of ~445x250, a smaller image of ~40x40, etc). While scrolling, the animation is extremely choppy.
Can someone recommend how I can improve performance?
One approach I tried was to eliminate any transparency in the images being used. This did improve it slightly, though there is still a noticeable lag when before a new item scrolls into view.
Update:
Here's the View heirarchy for the custom layout (for each item) - http://pastie.org/3333903
Looking at the layout provided, there are a few things that may cause performance issues:
Your View Hierarchy has a depth of 4. You should make your View Hierarchy as shallow as possible. Consider using a RelativeLayout/TableLayout where possible instead of nested LinearLayouts.
You have nested weights. Try to avoid having nested weighted views.
You have a lot of views for a row item. Remember the purpose of a ListView - if your rows start becoming complex, it may be a sign to look at something else to display this information.
A GestureOverlayView seems a bit heavy for a ListView row item. Is this necessary? Considering ListViews a scrollable by touch, having custom gestures on row items may be a bit confusing.
You can also try using android:persistentDrawingCache="scrolling" and the ViewHolder pattern to squeeze out a bit more performance.
If you download the latest version of ADT, it will also guide you in optimising your layouts.
Apart from layout optimisations, minimal work should be done in the getView method of your ListAdapter.
Additionally, you can use android:hardwareAccelerated="true" to take advantage of hardware in Android 3.0+.
You can use the dynamic table layout instead using the List view. It will improve the performance. Dynamic table layout will adjust the large image and smaller image. It will be of help to you.