# Layout Options

`LayoutOption` controls the visual layout and appearance of FwVideoFeedView widget. It determines how video thumbnails are arranged, spaced, and styled.

## Overview

`LayoutOption` provides comprehensive control over the feed's visual presentation, including:

* Layout type (grid, horizontal, vertical)
* Column count for grid layouts
* Spacing between items
* Thumbnail appearance (rounded corners, play icon)
* Feed title positioning
* Background colors

## Creating LayoutOption

### Using Builder

<pre class="language-kotlin"><code class="lang-kotlin">val layoutOption = LayoutOption.Builder()
    .feedLayout(FeedLayout.GRID)
    .columnCount(3)
    .itemSpacing(8)
    .roundedCorner(true)
<strong>    .build()
</strong></code></pre>

### Using DSL (Recommended)

```kotlin
val viewOptions = viewOptions {
    layoutOptions {
        feedLayout(FeedLayout.GRID)
        columnCount(3)
        itemSpacing(8)
        roundedCorner(true)
        roundedCornerRadius(12)
        backgroundColor(Color.parseColor("#F5F5F5"))
    }
}
```

## Properties

### feedLayout

**Type:** `FeedLayout` (enum)\
**Default:** `FeedLayout.HORIZONTAL`

Determines the layout type for displaying videos.

**Values:**

* `HORIZONTAL` - Horizontal scrolling row
* `VERTICAL` - Vertical scrolling column
* `GRID` - Multi-column grid

```kotlin
layoutOptions {
    feedLayout(FeedLayout.GRID)
}
```

### columnCount

**Type:** `Int`\
**Default:** `2`\
**Applies to:** Grid layout only

Number of columns in grid layout.

```kotlin
layoutOptions {
    feedLayout(FeedLayout.GRID)
    columnCount(3) // 3 columns
}
```

**Note:** This property only affects grid layouts. It's ignored for horizontal and vertical layouts.

### backgroundColor

**Type:** `Int` (color)\
**Default:** Transparent

Background color for the feed container.

```kotlin
layoutOptions {
    backgroundColor(Color.parseColor("#F5F5F5"))
    // or
    backgroundColor(Color.WHITE)
}
```

### feedPadding

**Type:** `FeedPadding` (data class)

**Default:** `null`

Sets the padding around the feed container. This controls the spacing between the feed content and its container edges.

**FeedPadding Parameters:**

| Parameter | Type  | Description                                         |
| --------- | ----- | --------------------------------------------------- |
| `start`   | `Int` | Start padding in pixels (left in LTR, right in RTL) |
| `top`     | `Int` | Top padding in pixels                               |
| `end`     | `Int` | End padding in pixels (right in LTR, left in RTL)   |
| `bottom`  | `Int` | Bottom padding in pixels                            |

**Tip:** Use `dpToPx()` extension for density-independent values:

```kotlin
layoutOptions {
    feedPadding(
        FeedPadding(
            start = 16.dpToPx(),
            top = 8.dpToPx(),
            end = 16.dpToPx(),
            bottom = 8.dpToPx()
        )
    )
}
```

**Use Cases:**

* Add horizontal margins to prevent content from touching screen edges
* Create vertical spacing between feed and other UI elements
* Support RTL layouts with start/end instead of left/right

**Note:** Unlike `itemSpacing` which controls spacing between items, `feedPadding` controls the outer padding of the entire feed container.

### itemSpacing

**Type:** `Int` (pixels)\
**Default:** 4dp

Spacing between feed items in pixels.

```kotlin
layoutOptions {
    itemSpacing(16) // 16 pixels between items
}
```

**Tip:** Use `dpToPx()` extension for dp values:

```kotlin
layoutOptions {
    itemSpacing(8.dpToPx()) // Convert 8dp to pixels
}
```

### roundedCorner

**Type:** `Boolean`\
**Default:** `false`

Enable or disable rounded corners on video thumbnails.

```kotlin
layoutOptions {
    roundedCorner(true)
}
```

### roundedCornerRadius

**Type:** `Int` (pixels)\
**Default:** `5` (when roundedCorner is true)

Corner radius for rounded thumbnails in pixels.

```kotlin
layoutOptions {
    roundedCorner(true)
    roundedCornerRadius(12.dpToPx())
}
```

**Note:** Only applies when `roundedCorner` is `true`.

### showPlayIcon

**Type:** `Boolean`\
**Default:** `true`

Show or hide the play icon overlay on video thumbnails.

```kotlin
layoutOptions {
    showPlayIcon(true)
}
```

### playIconWidth

**Type:** `Int` (pixels)\
**Default:** `24dp` (converted to pixels)

Width of the play icon on video thumbnails.

```kotlin
layoutOptions {
    showPlayIcon(true)
    playIconWidth(32.dpToPx()) // 32dp play icon
}
```

### showShoppingBagIcon

**Type:** `Boolean`\
**Default:** `false`

Show or hide the shopping bag icon overlay on video thumbnails. When enabled and the video has associated products, a small shopping bag icon is displayed on the thumbnail to indicate shoppable content.

```kotlin
layoutOptions {
    showShoppingBagIcon(true)
}
```

**Behavior:**

* `true` - A shopping bag icon is shown on thumbnails of videos that have associated products
* `false` - No shopping bag icon is displayed on thumbnails

**Note:** This only affects the feed thumbnail view. The shopping bag icon is not shown on videos without associated products regardless of this setting.

### shoppingBagIcon

**Type:** `ShoppingBagIcon` (sealed class)\
**Default:** `ShoppingBagIcon.Default` Customize the shopping bag icon appearance. Requires `showShoppingBagIcon` to be `true`.

#### **Data Structure**

```
ShoppingBagIcon (sealed class)
├── Default (object)          — Use the built-in icon, no customization.
└── CustomIcon (data class)   — Provide a custom icon with optional size.
        ├── image: WidgetImage          (required)
        └── size:  Pair<Int, Int>?      (optional, default = null)
```

**`WidgetImage`**

`WidgetImage` is the SDK's standard wrapper for a drawable resource with an optional tint:

```kotlin
data class WidgetImage(
    @DrawableRes val drawableRes: Int,       // Required. The drawable resource ID.
    @ColorInt    val tintColor: Int? = null,  // Optional. If null, no tint is applied.
)
```

| Parameter     | Type                   | Nullable | Description                                                                           |
| ------------- | ---------------------- | -------- | ------------------------------------------------------------------------------------- |
| `drawableRes` | `Int` (`@DrawableRes`) | **No**   | A valid Android drawable resource ID (e.g. `R.drawable.my_icon`).                     |
| `tintColor`   | `Int?` (`@ColorInt`)   | **Yes**  | A color int to tint the drawable. Pass `null` to keep the drawable's original colors. |

**`CustomIcon.size`**

| Parameter | Type              | Nullable | Description                                                                                                                              |
| --------- | ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `size`    | `Pair<Int, Int>?` | **Yes**  | Width (`first`) and height (`second`) in **pixels**. If `null`, the icon retains the default proportional sizing based on the thumbnail. |

#### **Usage Examples**

```kotlin
// 1. Default icon — no customization needed
layoutOptions {
    showShoppingBagIcon(true)
    shoppingBagIcon(ShoppingBagIcon.Default)
}
// 2. Custom icon, no tint, default size
layoutOptions {
    showShoppingBagIcon(true)
    shoppingBagIcon(ShoppingBagIcon.CustomIcon(
        image = WidgetImage(drawableRes = R.drawable.my_bag_icon),
    ))
}
// 3. Custom icon with tint, default size
layoutOptions {
    showShoppingBagIcon(true)
    shoppingBagIcon(ShoppingBagIcon.CustomIcon(
        image = WidgetImage(
            drawableRes = R.drawable.my_bag_icon,
            tintColor = Color.WHITE,    // nullable — pass null to skip tinting
        ),
    ))
}
// 4. Custom icon with explicit size (32×32 dp)
layoutOptions {
    showShoppingBagIcon(true)
    shoppingBagIcon(ShoppingBagIcon.CustomIcon(
        image = WidgetImage(R.drawable.my_bag_icon, Color.WHITE),
        size = 32.dpToPx() to 32.dpToPx(),  // nullable — pass null to use default sizing
    ))
}
```

### feedTitlePosition

**Type:** `FeedTitlePosition` (enum)\
**Default:** `FeedTitlePosition.NESTED`

Position of the feed title relative to video thumbnails.

**Values:**

* `NESTED` - Title overlays the thumbnail
* `STACKED` - Title appears below the thumbnail

```kotlin
layoutOptions {
    feedTitlePosition(FeedTitlePosition.STACKED)
}
```

### aspectRatio

**Type:** `Double`\
**Default:** 9:16

Custom aspect ratio for video items.

```kotlin
layoutOptions {
    aspectRatio(16.0 / 9.0) // 16:9 aspect ratio
    // or
    aspectRatio(9.0 / 16.0) // 9:16 aspect ratio
}
```

**Note:** If not specified, the SDK uses the 9:16 aspect ratio.

#### Thumbnail Selection Rules

{% hint style="info" %}
Format Requirements - The SDK currently supports JPG format images only.
{% endhint %}

The SDK selects thumbnails according to the following priority:

1. The system will automatically extract a frame from the video and generate a default thumbnail matching the video's aspect ratio
2. When only a Vertical Image Poster or Horizontal Image Poster is uploaded\
   The system will use the uploaded poster as the thumbnail
3. When both Vertical and Horizontal Image Posters are uploaded\
   The Carousel component will automatically select the poster image that most closely matches its Item's aspect ratio as the thumbnail<br>

## Default Values

| Property              | Default Value             |
| --------------------- | ------------------------- |
| `feedLayout`          | `HORIZONTAL`              |
| `columnCount`         | `2`                       |
| `backgroundColor`     | Transparent               |
| `feedPadding`         | `null`                    |
| `itemSpacing`         | `0`                       |
| `roundedCorner`       | `false`                   |
| `roundedCornerRadius` | `5` (when enabled)        |
| `showPlayIcon`        | `true`                    |
| `playIconWidth`       | `24dp`                    |
| `showShoppingBagIcon` | `false`                   |
| `shoppingBagIcon`     | `ShoppingBagIcon.Default` |
| `feedTitlePosition`   | `NESTED`                  |
| `aspectRatio`         | `9:16`                    |

## Layout Type Examples

### Horizontal Layout

Displays videos in a single horizontal scrolling row.

```kotlin
val viewOptions = viewOptions {
    layoutOptions {
        feedLayout(FeedLayout.HORIZONTAL)
        itemSpacing(12.dpToPx())
        roundedCorner(true)
        roundedCornerRadius(8.dpToPx())
    }
}
```

### Vertical Layout

Displays videos in a single vertical scrolling column.

```kotlin
val viewOptions = viewOptions {
    layoutOptions {
        feedLayout(FeedLayout.VERTICAL)
        itemSpacing(16.dpToPx())
        showPlayIcon(true)
    }
}
```

### Grid Layout

Displays videos in a multi-column grid.

```kotlin
val viewOptions = viewOptions {
    layoutOptions {
        feedLayout(FeedLayout.GRID)
        columnCount(3)
        itemSpacing(8.dpToPx())
        roundedCorner(true)
        aspectRatio(9.0 / 16.0)
    }
}
```

## Complete Examples

### Modern Grid Feed

```kotlin
class GridFeedActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_grid_feed)
        
        val videoFeedView = findViewById<FwVideoFeedView>(R.id.videoFeedView)
        
        val viewOptions = viewOptions {
            baseOptions {
                feedResource(FeedResource.Discovery)
            }
            layoutOptions {
                feedLayout(FeedLayout.GRID)
                columnCount(2)
                itemSpacing(12.dpToPx())
                roundedCorner(true)
                roundedCornerRadius(16.dpToPx())
                backgroundColor(Color.parseColor("#F8F9FA"))
                showPlayIcon(true)
                playIconWidth(40.dpToPx())
            }
        }
        
        videoFeedView.init(viewOptions)
    }
}
```

### Horizontal Story Feed

```kotlin
class StoryFeedActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_story_feed)
        
        val videoFeedView = findViewById<FwVideoFeedView>(R.id.videoFeedView)
        
        val viewOptions = viewOptions {
            baseOptions {
                feedResource(FeedResource.Channel(channelId = "your_channel_id"))
            }
            layoutOptions {
                feedLayout(FeedLayout.HORIZONTAL)
                itemSpacing(16.dpToPx())
                roundedCorner(true)
                roundedCornerRadius(12.dpToPx())
                showPlayIcon(false) // No play icon for story style
                aspectRatio(9.0 / 16.0)
            }
        }
        
        videoFeedView.init(viewOptions)
    }
}
```

### Product Gallery Grid

```kotlin
class ProductGalleryActivity : AppCompatActivity() {
    private fun loadProductVideos(productSku: String) {
        val videoFeedView = findViewById<FwVideoFeedView>(R.id.productVideos)
        
        val viewOptions = viewOptions {
            baseOptions {
                feedResource(
                    FeedResource.Sku(
                        channelId = "your_channel_id",
                        productIds = listOf(productSku)
                    )
                )
            }
            layoutOptions {
                feedLayout(FeedLayout.GRID)
                columnCount(3)
                itemSpacing(4.dpToPx())
                roundedCorner(true)
                roundedCornerRadius(8.dpToPx())
                showPlayIcon(true)
                playIconWidth(32.dpToPx())
            }
        }
        
        videoFeedView.init(viewOptions)
    }
}
```

## Important Notes

* `columnCount` only affects grid layouts
* `roundedCornerRadius` only applies when `roundedCorner` is `true`
* Item spacing is in pixels - use `dpToPx()` for density-independent values
* Aspect ratio can be calculated as `width.0 / height.0`
* Background color affects the feed container, not individual thumbnails
* Layout changes require re-initializing the feed view

## See Also

* [ViewOptions Overview](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/configuration) - Complete configuration system
* [BaseOption](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/configuration/base-options) - Content source configuration
* [FwVideoFeedView](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/configure-video-feed) - Video feed widget
* [TitleOption](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/configuration/title-options) - Feed title styling
