Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[Android] Tab screens stay clipped at a transient startup height for the whole session (onNativeLayout guard/report size mismatch)

未关闭
#555 1 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

@foxojs 已经在做这个了。

开始于 2026年7月20日。

  • #556 来自 @foxojs —— 未关闭

评估

难度
3/5
预计耗时
1-2 天
新手友好度
74/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
冷清
技术栈
android, kotlin, react-native
领域
mobile

调研方向

从 RCTTabView.kt 开始,跟踪布局变更监听器、其大小保护逻辑,以及报告给 JS 的 layoutHolder 尺寸。复现 issue 中描述的临时高度场景,并检查 Logcat 跟踪信息或链接 PR 中的复现。完成的标准是:后续的 layoutHolder 尺寸变化能够被报告,并且标签页界面在本次会话中不再持续处于被裁剪状态。

由索引模型根据 Issue 内容生成。

描述

Description

On Android, tab screens can get stuck clipped to a fraction of the window for the entire session: content renders in the top ~half of the screen with dead space below, while the tab bar, absolutely-positioned siblings, and pushed stack screens render normally. A force-close sometimes clears it; the race is per cold start. We observed this persistently in production on a Pixel 6a / Android 16.

Tab screen content latched at ~40% of the window with dead space below; tab bar and floating elements unaffected

Root cause

In RCTTabView.kt, the layout-change listener guards re-reporting on the outer view's size but reports the inner layoutHolder's size to JS:

val newWidth = right - left          // outer view (guard)
val newHeight = bottom - top
...
val dpHeight = Utils.convertPixelsToDp(context, layoutHolder.height)  // inner view (report)
...
lastReportedSize = Size(newWidth, newHeight)  // stores outer size

During startup the outer frame can settle at its final size while layoutHolder is still mid-layout at a transient height. If the listener fires in that window, the transient height is reported to JS and the outer size is latched into lastReportedSize. When layoutHolder finishes laying out, the outer size hasn't changed, so the guard never allows a re-report — the transient height is styled onto every tab screen for the rest of the session.

Regression from #283, which switched the reported size to layoutHolder without switching the guard.

Reproduction

Timing-dependent in the wild, but deterministic if you simulate the transient: force layoutHolder to a non-final height when the listener first fires, then restore it (snippet in the linked PR). On current main this latches the transient height with no further report; screens stay clipped. Logcat traces for both before and after the fix are in the PR.

Fix

Key the guard on layoutHolder's own dimensions — the same view whose size is reported — so any later correct layout is detected and re-reported (self-heals in a single frame; 5 ms measured in our repro). PR incoming.

🤖 Generated with Claude Code

主要语言
TypeScript
星标
1.5k
派生
110
平均合并
2 天 18 小时
30 天内合并 PR
2

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

callstack/react-native-bottom-tabs 的其他 Issue

查看 callstack/react-native-bottom-tabs 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。