Post
The blog is a work-in-progress started on Oct 8 '25, expected to last a few weeks

OSA Demo: Content Size Fitter Integration

Master dynamic item sizing with OSA’s Content Size Fitter demo. Learn how to create scroll views with items that automatically adjust their size based on content.

Contents

  1. Description
  2. Scene
  3. Code
  4. Summary

  5. Description

Your items may sometimes have different visual sizes, so the ContentSizeFitter approach comes to the rescue.

This scene uses a vertical ScrollView, but the same rules can be used to create a horizontal one as well.

Our example contains items which have their heights calculated based on their child’s text component

  1. Scene

[Screenshot - see Unity Asset Store documentation for visual guide]

We have an otherwise standard ScrollView structure.

[Screenshot - see Unity Asset Store documentation for visual guide]

Only the prefab is a bit different: it has a ContentSizeFitter component

[Screenshot - see Unity Asset Store documentation for visual guide]

It’s set up exactly the same as you’d do it when using a regular ScrollRect and a VerticalLayoutGroup component on its Content game object: The CSF has Vertical Fit set to Preferred Size and the children LayoutGroups take care of resizing themselves based on their own children. In this case, the TitleText reports its size to the TitlePanel, which together with Icon1Image report their sizes to the ItemPrefab’s HorizontalLayoutGroup and CSF components, the last one taking care of properly resizing the RectTransform.

Try resizing the item’s width to see how the height automatically adjusts to encapsulate the text completely

Two things to consider about the item prefab:

  1. It’s important to prevent the prefab from scaling with its parent’s height, so we bring all of its anchors together. It’ll have its height decided by the CSF anyway.

  2. In this vertical ScrollView example, the prefab’s Text will be oddly truncated if its Vertical Overflow property is set to Truncate. So as a general rule, set it to Overflow when you have similar scenarios. Likewise, if you have a horizontal ScrollView, the Horizontal Overflow property is the one to be modified. This may only happen on some Unity versions, but it’s good to set it up like this anyway:

[Screenshot - see Unity Asset Store documentation for visual guide]

  1. Code

The ContentSizeFitterSceneEntry ties some buttons in the Drawer to the adapter. The most important is the OnItemCountChangeRequested, which is called when you press “Set count”. Here, we’re just setting a new item count and the LazyDataHelper (see below) notifies the adapter about that change.

Now on the meat of our adapter, we’re using a LazyDataHelper, which creates item models only when they’re first accessed. This is the only way we could “show” 2 billion items. It takes the adapter itself as a parameter (so it can notify it on each change) and an Item creator delegate that it’s used to retrieve an item’s model the moment it’s first accessed, provided its index.

[Screenshot - see Unity Asset Store documentation for visual guide]

[Screenshot - see Unity Asset Store documentation for visual guide]

Each item has an icon and some text. The icon is just an index, because we sample them from a defined set of icons set in inspector (approx 10 icons), just for simplicity.

[Screenshot - see Unity Asset Store documentation for visual guide]

HasPendingSizeChange lets us know whether an item needs to be rebuilt or not. This one is set to true at any time the title changes, which makes sense, right?

The parameters contain the prefab property and the availableIcons which we use to retrieve items’ icons by IconIndex. Don’t worry about the other field for now.

[Screenshot - see Unity Asset Store documentation for visual guide]

The views holder contains the references to the UI elements that you’d expect: The title and the image.

[Screenshot - see Unity Asset Store documentation for visual guide]

For each views holder, its MarkForRebuild() is called when an external event might’ve just changed the ScrollView’s size (such as screen size changes), so the content size fitter must be enabled. RebuildLayoutDueToScrollViewSizeChange() callback will also be fired and you’ll set the HasPendingSizeChange on all of your models (that exist in memory, cached):

[Screenshot - see Unity Asset Store documentation for visual guide]

Its counterpart is UnmarkForRebuild(), and it’s called after its views were rebuilt.

Since we want the item’s index to also be included in the text, we have a separate method for that that only updates the text component, UpdateTitleByItemIndex(). We’ll also use this method when an item’s position changes, such as when items are removed or added before it - it makes sense, because not all of its contents change, only its index and thus, only its title:

[Screenshot - see Unity Asset Store documentation for visual guide]

ScheduleComputeVisibilityTwinPass(), which notifies the adapter that after the current “pass” (computation of all visible items’ positions), another (special) pass should be done because at least 1 item has changed its size. In other words, ScheduleComputeVisibilityTwinPass(), as the name implies, only schedules the pass, which is why we don’t care if it’s called multiple times in a row. The actual execution of a “twin” pass is done after the current pass.

The twin pass takes care of calling ViewsHolder’s MarkForRebuild() and UnmarkForRebuild() accordingly.

One thing to note here: If you call InsertItems() with endStationary=true , do the same for ScheduleComputeVisibilityTwinPass() to get consistent results.

This is also done in the UpdateViewsHolder(), whenever we detect an item’s content has changed. This callback is called each time an item becomes visible or during a “twin” pass:

[Screenshot - see Unity Asset Store documentation for visual guide]

The callback below is provided so we can acknowledge that the adapter has grabbed the item’s new size and so we can execute some code immediately, if we need to. We know the item now doesn’t need any pending size change, so we restore the properties that were prepared the item to have its size recalculated:

[Screenshot - see Unity Asset Store documentation for visual guide]

  1. Summary

  2. Whenever an item’s content changes, we set the model’s HasPendingSizeChange.

  3. Whenever UpdateViewsHolder() on an item is called and we detect that HasPendingSizeChange is true, we schedule a “twin” pass, which will schedule a layout rebuild on all visible items and grab their new sizes.

  4. For each visible item, the adapter calls OnItemHeightChangedPreTwinPass() where we disable set HasPendingSizeChange back to false.

  5. Whenever a visible item’s index changes, we only update its title and schedule a “twin” pass.

  6. Whenever we’re notified that the ScrollView’s size changes by a callback to RebuildLayoutDueToScrollViewSizeChange(), we set each of our existing (because LazyDataHelper only creates models on demand, not all at once) model’s HasPendingSizeChange to true. At the same time, each views holder is also notified by the adapter about this event by having its MarkForRebuild() called, where we enable the CSF.

In a nutshell, an item’s ContentSizeFitter component is enabled whenever we need it to calculate the item’s size for us, after which is disabled. OSA has a special “twin” pass that can be scheduled for execution on demand whenever we detect that one or more items need their size to be recalculated.

this post is licensed under cc by 4.0 by the author.

© Forbidden Byte. some rights reserved.

other searches include optimised scrollview adapter, optimized scroll view adapter, optimized scrollvew adapter, optimzed scrollview adapter, optmized scrollview adapter, optimized scrolview adapter, optimized scrollview adaptor, optimized scrollveiw adapter, optimized scrollview adpater, osa unity, mediaplayer8, media player 8, mediaplayer8 unity, media player unity, scene objects query, sceneobjectsquery, scene object query, soq unity, unity video player plugin, unity scene query tool, scroll rect optimizer, unity list view, unity grid view