Open Danielku15 opened 2 years ago
As an update: I built the following custom layout manager which allows me to inject a custom width into the FlexboxLayoutManager
. With this adjustment it is possible to have dual scrolling as described. At least this proofs that the core functionality would be available, but: it breaks the virtualization/recycling of items on horizontal scrolling. If I have only 1 line with 100 items, the RecyclerView
creates 100 ViewHolder
s and binds them all instead of only holding the items in the visual viewport.
I guess this comes from the fact that I am actually telling the RecyclerView that the full width of the layout is spanning the 100 items. I fear without changes in the library this cannot be fixed. The FlexboxLayoutManager
would need to do the layouting and scrolling logic based on a virtual width, while keeping the actual with actual width.
class MyLayoutManager : FlexboxLayoutManager {
private var _width: Int = 0
constructor(context: Context?) :
super(context, FlexDirection.ROW, FlexWrap.WRAP) {
justifyContent = JustifyContent.FLEX_START
alignItems = AlignItems.FLEX_START
}
override fun canScrollHorizontally(): Boolean {
return true
}
override fun canScrollVertically(): Boolean {
return true
}
override fun getWidth(): Int {
return Math.max(_width, super.getWidth())
}
fun setWidth(value: Int) {
_width = value
requestLayout()
}
}
My use case is the follwing: I am having a music notation engraver which takes care of the precise layouting of the measures (green boxes) according to some custom configurations. As the rendered green boxes are in-memory bitmaps this is very costly in terms of memory. To solve this, I encode each frame into PNGs (for now still in-memory) and decode them dynamically again when shown on screen.
My next level optimization would be to have a 1st level and 2nd level cache to keep items close to the viewport in-memory and the ones far away even on disk (some cache directory).
Issues and steps to reproduce
I would like to use the
FlexboxLayoutManager
within aRecyclerView
to achieve a dual scrolling like in aWebView
. My goal is to a have a left to right layouting with wrapping, but each row can potentially exceed the viewport.According to the Source Code the layout manager can handle both kinds of scrolling but the layouting and scrolling behavior is heavily dependent on the size of the RecyclerView. The size of the RecyclerView is constraint to its usage in the app which is correct. But unfortunately the FlexboxLayoutManager does all the layouting based on the actual size of the RecyclerView. I am using
FlexDirection.Row
andFlexWrap.Wrap
to get the left-to-right layouting with wrapping at the "end".But unfortunately the wrapping always happens at the width of the RecyclerView (black) and not at a custom virtual width (red). Is there some hidden way to achieve what I want to achieve (e.g. through overriding some methods).
Version of the flexbox library
3.0.0
Link to code
I guess you can just take the
demo-cat-gallery
app from this repository. There try to get a dual scrolling which allows scrolling horizontally 2x the viewport and the remaining vertical depending on the number of cats.