SuperAPI AI Directory

kuikly-visibility-exposure

General & other

View repository

Updated 10-15 23:56

About this skill

Kuikly Exposure and Visibility Events

Core Concepts

Kuikly provides a completecomponent visibility event system, used to listen for changes in a component's visibility state within a scrolling container or page. Four key elements:

  1. Visible window: the nearest scrolling container (Scroller/List/WaterfallList), ModalView, or Pager
  2. Visibility state: four states + percentage (WILL_APPEAR → DID_APPEAR → WILL_DISAPPEAR → DID_DISAPPEAR)
  3. Trigger timing: scroll offset changes, child view layout completion, visible area margin changes, component removal
  4. Application scenarios: exposure reporting, lazy loading, playback control, visible percentage monitoring

Visible Window Lookup Rules

The system starts from the component's parentand traverses upward, finding the first matching ancestor as the visible window:

组件 → parent → ... → ScrollerView(Scroller/List/WaterfallList/PageList)→ 命中
                     → ModalView → 命中
                     → Pager → 命中(兜底)
  • For ScrollerView(Scroller/List/WaterfallList): visibility is based on thelist visible areacalculation, subtracting the scroll offset
  • For ModalView: visibility is calculated based on the Modal's layout frame
  • For Pager: visibility is calculated based on the page's layout frame

Important: visibility is relative to thevisible area of the nearest scrolling container, not the screen position. If screen-position visibility is needed, in nested scrolling container scenarios, you can use the scroll event callback of the outer scrolling container, combined with the list offset, to calculate the node's actual position.

State Machine

                    ┌──────────────────────────────────────────────┐
                    │                                              │
                    ▼                                              │
  DID_DISAPPEAR ──→ WILL_APPEAR ──→ DID_APPEAR ──→ WILL_DISAPPEAR ─┘
  (完全不可见)       (部分可见)       (完全可见)       (部分可见)

Three spatial relationships and state transitions:

Spatial relationship Determination condition State transition
Separate(the component is completely outside the window) The component frame has no intersection with the window → WILL_DISAPPEAR → DID_DISAPPEAR
Contained(the component is completely inside the window) The component frame is completely inside the window → WILL_APPEAR → DID_APPEAR
Intersecting(the component is partially inside the window) The component frame partially overlaps with the window From DID_DISAPPEAR → WILL_APPEAR; from DID_APPEAR → WILL_DISAPPEAR

Special behavior:

  • When the component isremoved(v-if removal, page destruction, etc.), WILL_DISAPPEAR → DID_DISAPPEAR is automatically triggered, and percentage is set to 0
  • State changes areasynchronous(scheduled via addNextTickTask ), except when the page is destroyed (executed synchronously)

API Quick Reference

Visibility events

Event Description Callback parameters import
willAppear { } The component is about to become visible (partially entering the window) None com.tencent.kuikly.core.base.event.willAppear
didAppear { } The component is fully visible (completely inside the window) None com.tencent.kuikly.core.base.event.didAppear
willDisappear { } Component is about to become invisible (partially leaving the window) None com.tencent.kuikly.core.base.event.willDisappear
didDisappear { } Component is completely invisible (entirely outside the window) None com.tencent.kuikly.core.base.event.didDisappear
appearPercentage { } Change in component visible percentage percentage01: Float([0,1]) com.tencent.kuikly.core.base.event.appearPercentage

appearPercentage percentage calculation logic

Spatial relationship percentage value
Completely invisible(disjoint) 0
Completely visible(contained) 1
Partially visible(intersecting) Vertical list:可见高度 / 组件高度; Horizontal list (FlexDirection.ROW / ROW_REVERSE):可见宽度 / 组件宽度

The percentage value is always clamped to the range [0, 1]. The callback is triggered only when the percentage changes.

Scroller/List/WaterfallList auxiliary properties

Property Description Parameter type Supported containers
visibleAreaIgnoreTopMargin(margin) Crop the specified height from the top of the visible window Float Scroller、List、WaterfallList
visibleAreaIgnoreBottomMargin(margin) Crop the specified height from the bottom of the visible window Float Scroller、List、WaterfallList

How it works: Shrinks the list's "visibility determination window". After setting, visible window height = list height - marginTop - marginBottom, and child component Y coordinates are also reduced by marginTop. For example, with a list height of 500dp, after setting visibleAreaIgnoreTopMargin(60f) and visibleAreaIgnoreBottomMargin(80f) , only child components within the middle 360dp area of the list will be determined as visible.

Typical scenario: The top/bottom of the list has fixed occluding UI (such as a floating navigation bar, semi-transparent overlay, or bottom toolbar). Child components within the occluded area are "visible" in the list coordinate system, but the user cannot actually see them, so they need to be excluded from exposure determination.


Quick start

didAppear exposure reporting

import com.tencent.kuikly.core.base.event.didAppear

View {
    attr {
        size(100f, 100f)
        backgroundColor(Color.GREEN)
    }
    event {
        didAppear {
            // 组件完全可见,执行曝光上报
        }
    }
}

appearPercentage visible percentage listening

import com.tencent.kuikly.core.base.event.appearPercentage

View {
    attr {
        size(100f, 100f)
        backgroundColor(Color.GREEN)
    }
    event {
        appearPercentage { percentage01 ->
            // percentage01 为 [0,1] 的露出百分比
            // 1 表示 100% 可见,0 表示 0% 可见
            if (percentage01 >= 0.5f) {
                // 超过 50% 可见时执行逻辑
            }
        }
    }
}

Full lifecycle listening

import com.tencent.kuikly.core.base.event.willAppear
import com.tencent.kuikly.core.base.event.didAppear
import com.tencent.kuikly.core.base.event.willDisappear
import com.tencent.kuikly.core.base.event.didDisappear
import com.tencent.kuikly.core.base.event.appearPercentage

View {
    event {
        willAppear {
            // 组件将要可见(部分进入窗口)
        }
        didAppear {
            // 组件完全可见 → 曝光上报
        }
        willDisappear {
            // 组件将要不可见(部分离开窗口)
        }
        didDisappear {
            // 组件完全不可见
        }
        appearPercentage { percentage ->
            // 可见百分比变化
        }
    }
}

visibleAreaIgnoreMargin excludes occluded areas

import com.tencent.kuikly.core.base.event.didAppear

Scroller {
    attr {
        flex(1f)
        // 顶部 60dp 区域内的子组件不参与曝光判定
        visibleAreaIgnoreTopMargin(60f)
        // 底部 80dp 区域内的子组件不参与曝光判定
        visibleAreaIgnoreBottomMargin(80f)
    }

    View {
        attr {
            height(120f)
            backgroundColor(Color(0xFFE3F2FD))
        }
        event {
            didAppear {
                // 只有完全进入中间有效区域(500 - 60 - 80 = 360dp)时才触发
            }
        }
    }
}

Common mistakes and pitfalls

Incorrect approach Correct approach Reason
❌ The root node uses didAppear to listen for page exposure ✅ Use the page lifecycle pageDidAppear() The root node has no scrolling container as a visible window, so behavior is unpredictable
❌ Assuming visibility is relative to screen position ✅ Visibility is relative to thevisible area of the nearest scrolling container If screen position is needed, calculate it in combination with the scroll event offset
❌ Directly perform exposure reporting in appearPercentage directly execute exposure reporting in ✅ For exposure reporting use didAppear, or add a threshold + deduplication flag appearPercentage triggers on every scroll, at an extremely high frequency
❌ Forgetting to import the visibility event extension function ✅ Add the corresponding import statement These are Event extension functions, which require an explicit import

Complete usage example

See EXAMPLES.md